Classloader in Applet: Can't access files

2019-08-02 09:24发布

问题:

I have an application that uses reflection to instantiate code saved in some directory: I create a URLClassLoader that then loads the classes using the URLs provided; this works fine. I tried to port the application to an Applet. For loading text files and images, I changed the code from using relative paths to use getResourceAsStream() which works great. For the class loader, however, I still have an I/O exception (which I also used to get with the text files and images before I changed the code to use streams):

java.security.AccessControlException: access denied (java.io.FilePermission /.../... read)

The classes to be loaded are contained in the jar file (as are all the other resources). Is there any way to load classes using something like getResourceAsStream() that does not invoke a security exception? Please note: I am talking about a class loader invoked from within the java code, not the class loader that loads the applet.

EDIT: More details on the file/folder structure:

My applet is in a package a, a.MyApplet, which makes use of a class a.aa.Loader which is meant to load classes stored in another folder b (hence not loaded when the applet is loaded). The folder b contains many directories, b.c_i, where c_i is a unique directory. In each of these directories are classes that belong to a package x.y.z, so the overall folder structure of b is b.c_i.x.y.z; z contains the file to be loaded. When I create the jar, the top-level looks like follows ([] indicates folder): [a],[b],[data],[images] where [a]={MyApplet,[aa],[aaa],etc.} and [b]={c_1,_c2,...} where c_i={[x]}, [x]={[y]}, [y]={[z]} and finally [z]={Class.class}. Hope the notation is not too weird.

Edit2: More details.

To clarify: the classes I want to load are classes by other people, all placed in a separate directory "DIR" (they are not part of the project nor do they form a project themselves). In fact, all these class names are identical, they are stored in unique directories within "DIR". I need to load one file at a time. In other words, I would like to treat the class files like any other resource.

NOTE: I tried a signed applet and it no longer throws a security exception but an IO one: it can not locate the file. I checked the directory structure and tried numerous variants, all with the same outcome (it works on my local machine). I am not sure if it is really an IO problem or whether it is still a security issue.

回答1:

Actually, keeping a project as a separate objects range that's a bad tone so...

  • You can just pack all your project to a single jar file.

  • In the case you keep your classes on server just because the whole project is too big you can compress it with pack200 util which is very helpful for Java Web Start fat client applets

  • And I do recommend use jnlp applet launch type because it provides more options with its DeployJava.js

P.S.

And if you really insist to load resources with class loader do it in a applet standard manner I mean with an Anchor object

for example create structure like

  • |- package images -
  • |imageA.png
  • |imageB.png
  • |Anchor.class
  • |SourceBound.class

SourceBound.java

public class SourceBound
{

  /**
    Conception only...
  **/
  public SourceBound(){}

  public ImageIcon getImageA()
  {
    ImageIcon icon;
    Image image;

    image=ImageIO.read(Anchor.class.getResourceAsStream("imageA.png"));
    icon=new ImageIcon(image);

    return icon;
  }
}

  • |package test
  • |Test.class

Test.java

public class Test
{

SourceBound sourceBound=new SourceBound();

Test()
{
  JButton button=new JButton();
  button.setIcon(sourceBound.getImageA());

}

}

Good luck