Solved

Reading files from within an applet - signed applets

Posted on 1998-07-14
22
206 Views
Last Modified: 2013-12-29
I want to implement a JApplet which shows a JTable. This JTable's contents are feed by a database. Reading from this database works well... at least in the AppletViewer (I have to check if this doesn't work in a browser...).

After I have read the data and displayed them I want to update some data. To do this I need to access to some files located on another server. An AppletSecurityException is the result of doing this.
How can I make this going? Here's the code of the method I use:
  public Vector updateCourses(String symbol)
  {
        Vector update = null;

            String latestCourse_URL = "tcx_data/ebf/hour/";

            URL url = null;
            try
            {
                  url = new URL(getDocumentBase(), latestCourse_URL+symbol+".hour");
                  BufferedReader br = new BufferedReader(new FileReader(
                                                                                          latestCourse_URL+symbol+".hour"));
                  try
                  {
                        String line = br.readLine();
                        String theDate = "";
                        String theCourse = "";
                        int index0 = tableBean.getModel().findColumn("AKT. KURS");
                        //int index1 = tableBean.getModel().findColumn("letzteAktualisierung");
                        while (line != null)
                        {
                              StringTokenizer t = new StringTokenizer(line);
                              theDate = t.nextToken() + " " + t.nextToken();
                              theCourse = t.nextToken();
                              line = br.readLine();
                        }// end while
                        //tableBean.getModel().setValueAt(theCourse,4,index0);
                        update = new Vector();
                        update.addElement(theDate);
                        update.addElement(theCourse);
                        br.close();
                  }// end try
                  catch (IOException IOe)
                  {
                        System.err.println("IOException " + IOe);
                        return null;
                  }// end catch
            }// end try
            catch (MalformedURLException MURLe)
            {
                  System.err.println("MalformedURLException " + MURLe);
                  return null;
            }// end catch
            catch (IOException IOe)
            {
                  System.err.println("IOException " + IOe);
                  return null;
            }// end catch

            return update;
      }//end updateCourses

I need help, since I have to solve this problem to complete my final exam!!!

Thanks for your help!

PS: A program I have written with JDK 1.0.2 ALLOWS a similar access this way:
...
                         url = new URL(docBase, germanStocks_URLpath/*"tcx_data/ger_stamm.txt"*/);
                         DataInputStream dis = new DataInputStream(url.openStream());
                         try
                         //Read out the stocks names and numbers (WKN)
                         {
                               String line = dis.readLine();
 ...

If the only possibility to do this is by using signed applets, how would I have to do this? Which files must I create and how must they be configured? How would I have to use javakey and how does javakey works (where is the database used by javakey located, how would I have to make entries,...)?
0
Comment
Question by:dirku
  • 12
  • 9
22 Comments
 

Author Comment

by:dirku
ID: 1226075
Edited text of question
0
 
LVL 5

Accepted Solution

by:
msmolyak earned 50 total points
ID: 1226076
After line
     url = new URL(getDocumentBase(), latestCourse_URL+symbol+".hour");
instead of using a reader,
    BufferedReader br = new BufferedReader(new FileReader(
    latestCourse_URL+symbol+".hour"));
simply open this URL's input stream by
    InputStream is = url.openStream();
You can construct a Reader on top of that stream.
The applet is allowed to read files cominng from the same HTTP server it came from.
0
 

Author Comment

by:dirku
ID: 1226077
I have changed the above lines as follows:
                  url = new URL(getDocumentBase(), latestCourse_URL+symbol+".hour");
                  InputStream is = url.openStream();
                  InputStreamReader isr = new InputStreamReader(is);
                  BufferedReader br = new BufferedReader(isr);
.

The kind of exception now has changed.
Since the Oracle database is located on another host in our LAN (what is OK when using AppletViewer - I can access all the data on the foreign machine) I have changed the database to a MS Access database on the machine where I develop the applet (and I changed the JDBC-driver, of course).
The following is what I can see now in the Java-Console from the browser.
Any suggestions?

netscape.security.AppletSecurityException: security.class from local disk trying to access url: file:/C|/Java/IDE/Kawa30/Projects/Pm/tcx_data/ebf/hour/1kFFRE3.hour
  at java.lang.Throwable.<init>(Compiled Code)
  at java.lang.Exception.<init>(Compiled Code)
  at java.lang.RuntimeException.<init>(Compiled Code)
  at java.lang.SecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurity.checkURLConnect(Compiled Code)
  at java.lang.SecurityManager.checkURLConnect(Compiled Code)
  at netscape.net.URLConnection.connect(Compiled Code)
  at netscape.net.URLConnection.getInputStream(Compiled Code)
  at java.net.URL.openStream(Compiled Code)
  at PM.updateCourses(Compiled Code)
  at PM.gatherSymbols(Compiled Code)
  at PM.createTable(Compiled Code)
  at PM.init(Compiled Code)
* at netscape.applet.DerivedAppletFrame$InitAppletEvent.dispatch(Compiled Code)
  at java.awt.EventDispatchThread$EventPump.dispatchEvents(Compiled Code)
  at java.awt.EventDispatchThread.run(Compiled Code)
  at netscape.applet.DerivedAppletFrame$AppletEventDispatchThread.run(Compiled Code)
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226078
Why are we talking about databases? Aren't you just trying to access a file from the server?

How are you loading your applet? Make sure that your applet is not loaded from the local CLASSPATH but from the HTTP server. You can check that by strating the browser and turning the debug mode on in the Java Console (by typing 9) before starting the applet. The messages will tell you where the Java classes are being loaded from. If you are loading the applet from CLASSPATH it will behave differently then when loaded from the Web server. Namely it will not be allowed to open any URLs. If you are running the applet on the machine where the class files are, remove the CLASSPATH variable and try running again.
0
 

Author Comment

by:dirku
ID: 1226079
I'm sorry, Michael,

I didn't correctly mentioned what I intend to do.

In the end the applet should be run on a server where the database is located as well as some files which I want to read out.
These files contain up-to-date values which should be inserted into the tables of the database.

This means, I want the applet to display a JTable built from some entries in the database. After clicking a button I want to update some cell values with the content of some other files located on the host where the databse is located, too.
After updating the new values of the table in the applet the values of the cells in the applet's table should be stored into the database again.

While programming I thought I could have everything on my local machine which means that I have the JDK here as well as the database (MS Access for testing), as well as the files which are used to update.

C:\JAVA\JDK1.1.6\BIN    ---> the JDK
C:\JAVA\PROJECT\MyProject\  ---> the class files
C:\JAVA\PROJECTS\MyProject\DB\MyDatabase.mdb  ---> the database
C:\JAVA\PROJECTS\MyProject\data\*.*    ---> the files containing the new values

Can't I do this? I just want to minimize WWW-access as possible.

As I told you, I did it this way with a previous program (without accessing a database but reading out some files to display these values in an applet).

Again, I'm sorry for being such unclear.
Ah ja, even when setting no CLASSPATH it doesn't run! :-((

[ simple file ]--read into applet---->[ MyApplet ]<---read from/into database---->(database)

I hope it's clear now.
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226080
Again, since we are talking about reading the files over the net, the rule is simple. If your file is loaded from the HTTP server, you can read the files residing on that server (using the appropriate URL). If the applet is loaded from the CLASSPATH, it cannot read files from disk.

It is easy to check how the applet is loaded. To do it, start the browser, open Java console and type "9" there. Then run your applet. The console will tell you where each class is loaded from.

There are ways for applets to get outside their security sandbox (and read files from any host for example), but that requires special effort.
0
 

Author Comment

by:dirku
ID: 1226081
When setting the CLASSPATH in the AUTOEXEC.BAT Netscape Navigator 4.05 shows the following lines in the Java Console:
.
# Applet PM initialized
# Applet PM running
java.lang.NullPointerException
  at PMTableBeanModel.getColumnClass(Compiled Code)
  at com.sun.java.swing.JTable.getColumnClass(Compiled Code)
  at com.sun.java.swing.plaf.basic.BasicTableUI.getCellRenderer(Compiled Code)
.

Since there is a JComboBox in the Applet which is initialized before the JTable this JComboBox appears in the JApplet and when clicking on it the list pops up and the items are the ones which are stored in the database, thus the database access seems to be granted. When hiding the list of the JComboBox the JTable appears in the area of the JComboBoxes pop-up list. Thus, the acces to the database for reading out the table values seems to work well, too.

The remaining question is: Why does this NullPointerException occur? Do you have any idea? When the browser is the active window I can see that messages of this NullPointerException appears permanently which lets me assume that some fired events causes this (maybe the fireTableStructureChanged method from the TableModel?).

However, presently I have commented out the part of the code where I try to access the local file because I think that this would be granted (because I have access to the database!) when the problem of the NullPointerException mentioned above is eliminated.

I suppose such a "long-distance-analysis" is hardly to do but I hope you have some suggestions.

However, I'll grade you with an A since you have lead me on the right way and I hope you will help me with this current problem even after obtaining the points?!!

Thank you, Michael.

Regards, Dirk
ulrich@tembit.com
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226082
Looks like the exception is thrown in your class. Can't you isolate the line where it is thorwn by inserting println() statements. Usually NPE are easy to track.
0
 

Author Comment

by:dirku
ID: 1226083
After creating the tableModel and the table(UI) itself I add some columns to the model. I do it by invoing the setColumnNames(String name) method from the tbaleModel (which extends the AbstractTableModel).

in main:
tableModel.setColumnNames("CAPITAL");

in tableModel:
      public void setColumnNames(String name)
      {
            int len = columnNames.length;
            String[] tmp0 = new String[len];
            for(int i=0; i<len; i++)
                  tmp0[i] = columnNames[i];

            columnNames = new String[len+1];
            for(int i=0; i<len; i++)
                  columnNames[i] = tmp0[i];
            columnNames[len] = name;
            tmp0 = null;
            
            addColumn();
            fireTableStructureChanged();
      }

the method addColumn invoked from setColumnNames located in the tableModel, too:
      private void addColumn()
      {
            Object[][] tmp = new Object[data.length][columnNames.length];
            
            for(int i=0; i<data.length; i++)
                  for(int j=0; j<columnNames.length; j++)
                  {
                        if( j == columnNames.length-1 )
                              tmp[i][j] = "";
                        else
                              tmp[i][j] = data[i][j];
                  }//end for j
            
            data = new Object[tmp.length][columnNames.length];
            for(int i=0; i<tmp.length; i++)
                  for(int j=0; j<columnNames.length; j++)
                        data[i][j] = tmp[i][j];

      }//end addColumn

As you can see I store the data which I retrieve from the database in the Object[ ][ ] data.

The Java Console of the Navigator throws the exception when trying to invoke the getColumnClass method.
Maybe you can see anything more now?

# Applet PM initialized
# Applet PM running
java.lang.NullPointerException
  at PMTableBeanModel.getColumnClass(Compiled Code)
  at com.sun.java.swing.JTable.getColumnClass(Compiled Code)
  at com.sun.java.swing.plaf.basic.BasicTableUI.getCellRenderer(Compiled Code)
0
 

Author Comment

by:dirku
ID: 1226084
When commenting out the line "fireTableStructureChanged();" in the setColumnNames() method the complete table will be displayed in the Navigator but, of course, without the new Columns. I think when adding some columns to the model I have to fire this event, haven't I?

Furthermore I still have commented out the method invokation of updating the values right when starting the applet. But when using the menu item to update the courses I still receive an exception. (Which will be the next problem to solve!)
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226085
Check the implementation of getColumnClass() (it is either yours or it is from an abstract model class whose code is available). See what can cause NPE there. Most probably the column itself is null.

Another suggestion is to run your program as an application which would allow you to use the debugger (even without it you can get exact line numbers where the exception occured).
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:dirku
ID: 1226086
I found out that my implementation (although I have taken it from the Java tutorial, I think) doesn't work well. When deleting this method the program becomes visible completely in the Navigator even with the manually added columns but: Whenever choosing the menu item to update the cell values (from locally files which results in an exception until now) these manually added columns will be added again.
After eliminating this problem we could go on making the cell values become updated. OK?
(Maybe an idea why the columns are added again and again?)
0
 

Author Comment

by:dirku
ID: 1226087
Here's the getColumnClass which I havae had implemented and now erased:
      public Class getColumnClass(int col)
      {
            return getValueAt(0, col).getClass();
      }

0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226088
Could you make sure that getValueAt(0, col) does not return null.
0
 

Author Comment

by:dirku
ID: 1226089
The program works well now. Since I wrote my program this way that whenever a row will be added to the table/table's model the row should be written to the database and then read out again with the query used before. (I know that this is surely inefficient but I have to make the applet run because the end of the final exam is in the first week of August! If you have a better alternative I'd appreciate to hear it.)
After reading again the manually added columns which contains some calculated values of the columns loaded out of the database) are away and I must find a way that these columns/cells will be added again.

Maybe there is a possibility to alter the SQL statement in a way to load "virtual columns"? I mean with the SELECT statement I load existing columns from a table which then will be displayed.
Is it possible to say in this SELECT statement that I wish to obtain three more columns which have a label I say (eg. "CAPITAL")?
I would need the three columns "CAPITAL", "LATEST PRICE" and "LAST UPDATE".
In the LAST UPDATE-column I want to insert the date and time of the last online access to the update files.
In the LATEST PRICE-column I want to insert the price which I have obtained from the last updating which is documented in the LAST UPDATE-column.
In the CAPITAL-column I want to insert a value which is calculated by the values of: LATEST PRICE * NUMBEROF - CHARGES.

If I could say in the SELECT statement that I want three more columns than the particular ones I have defined by "SELECT col1, col2, col5 FROM ..." I don't have to add them manually and after writing to the database and then immediately reading them with this SELECT statement again I don't have the problem that they aren't there anymore after it. (I hope you understand what I intend to do?!)
Of course, inserting the values to these three columns depends on solving the old following problem described by the following
output of the Navigator's Java Console when running the applet:

.
netscape.security.AppletSecurityException: security.class from local disk trying to access url: file:/C|/Java/IDE/Kawa30/Projects/Pm/tcx_data/ebf/hour/1kFFRE3.hour
  at java.lang.Throwable.<init>(Compiled Code)
  at java.lang.Exception.<init>(Compiled Code)
  at java.lang.RuntimeException.<init>(Compiled Code)
  at java.lang.SecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurityException.<init>(Compiled Code)
  at netscape.security.AppletSecurity.checkURLConnect(Compiled Code)
  at java.lang.SecurityManager.checkURLConnect(Compiled Code)
  at netscape.net.URLConnection.connect(Compiled Code)
  at netscape.net.URLConnection.getInputStream(Compiled Code)
  at java.net.URL.openStream(Compiled Code)
  at PM.updateCourses(Compiled Code)
  at PM.gatherSymbols(Compiled Code)
  at PM.createTable(Compiled Code)
  at PM.init(Compiled Code)
* at netscape.applet.DerivedAppletFrame$InitAppletEvent.dispatch(Compiled Code)
  at java.awt.EventDispatchThread$EventPump.dispatchEvents(Compiled Code)
  at java.awt.EventDispatchThread.run(Compiled Code)
  at netscape.applet.DerivedAppletFrame$AppletEventDispatchThread.run(Compiled Code)
# Applet PM can't start: ERROR
#   status=0


0
 

Author Comment

by:dirku
ID: 1226090
OK. Maybe it's a quick-and-dirty way but when reading a column twice now contents are displayed in the second, third, fourth, ... column. I have selected this way: SELECT trade_price AS PRICE, trade_price AS CAPITAL, trade_price AS YIELD ...". This way three more columns are visible and now I have to determine the values to be filled in their cells.
So I need to have the access to the local files (or in the end to the files on the web server where the database as well as the applet's class files will be stored.

But how...?
0
 

Author Comment

by:dirku
ID: 1226091
So, this means that I can only run my applets with a web server?

Some months ago I have developed another applet which needed to read some files, too, and it runs when testing it on my PC. (I have developed it with Microsoft Visual J++ 1.1 so I don't know if this IDE makes it going!)

I have ever thought that an applet is allowed to access the local file system of the mahcine on which it is run.
So, when I have the class files in the directory C:\MyProg and the files to be read out are in this directory, too, the applet is granted access to these files.

Could you tell me the difference between getCodeBase() and getDocumentBase()?

And, I think after this I should begin again to pay for my questions, shouldn't I?

Thanks for your help and patience, Michael.
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226092
Yeah, could you post any additional questions you have separately.
----------------
getDocumentBase

 public URL getDocumentBase()

     Gets the document URL. This is the URL of the document in which the applet is embedded.

     Returns:
          the URL of the document that contains this applet.
     See Also:
          getCodeBase
getDocumentBase

 public URL getDocumentBase()

     Gets the document URL. This is the URL of the document in which the applet is embedded.

     Returns:
          the URL of the document that contains this applet.
     See Also:
          getCodeBase

----------------

getCodeBase

 public URL getCodeBase()

     Gets the base URL. This is the URL of the applet itself.

     Returns:
          the URL of this applet.
     See Also:
          getDocumentBase

Why don't you print both in your applet. I will see the difference then.
0
 
LVL 7

Expert Comment

by:linda101698
ID: 1226093
msmolyak,
I am going to post a question in this topic area to award you additional quality points for your answer.  The question was accidently graded incorrectly.  See comment copied below.

Linda Gardner
Customer Service @ Experts Exchange


   From: dirku
                                        Date: Monday, July 27 1998 - 09:31AM PDT
   This morning I have given the grade "C" to msmolyak because he had answered
   my question. Now, in the evening I saw my last grades given account and the
   mistake I have made. A mistake because I wanted to give him an "A".
   Can you change the grade from "C" to "A"?
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226094
Thank you, Dirk, I appreciate it.
0
 

Author Comment

by:dirku
ID: 1226095
Any idea to my question from yesterday?
Title: "Unwanted ListSelectionEvent when using JComboBox"
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 1226096
I've seen your question but I need to actually write a sample program to try it. I did not have an answer of the top of my head. I'll get to it if I have time.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
The viewer will learn how to implement Singleton Design Pattern in Java.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now