I ran across an issue when attempting to port an application over to JApplet
so it can run on a browser.
Program Contents:
- Jar file. Contains my
CustomClassLoader
implementation. Stored on website. - Content directory. Filled with compiled classes. Stored on the users computer.
Issue:
I am getting a NoClassDefFoundError
when attempting to load .class files in the content directory with my CustomClassLoader
.
The error, although unattainable, relates back to a class inside the jar. The class is abstract. All the .class files in the content directory extend this class and fill all the required methods. Upon loading these classes, the error is thrown. The program, when ran normally java -jar file.jar
, works perfectly fine.
This makes me believe it has to do with the classpath.
Security Setup:
I am running the applet through the appletviewer
command like so:
appletviewer -J-Djava.security.policy=policy file.html
In the same directory is my policy file:
grant {
permission java.lang.RuntimePermission "getenv.APPDATA";
permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete, execute";
permission java.lang.RuntimePermission "exitVM";
permission java.util.PropertyPermission "user.name", "read";
permission java.lang.RuntimePermission "createClassLoader";
};
As far as I know, no other security exceptions are being thrown. The applet is signed.
HTML File Used To Load Applet:
<!DOCTYPE html>
<html>
<body>
<object width="1000" height="600" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab#Version=1,4,0,0">
<param name="archive" value="file.jar"/>
<param name="code" value="package.to.Boot"/>
</object>
</body>
</html>
Any help towards fixing this problem is greatly appreciated.
CustomClassLoader.java:
package org.obicere.cc.methods;
import java.io.File;
public class CustomClassLoader extends ClassLoader {
//...
private Class<?> loadClass(final File file) {
try {
final byte[] data = IOUtils.readData(file);
return super.defineClass(file.getName().substring(0, file.getName().length() - 6), data, 0, data.length);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Example Runner: CanReachRunner.java
import java.lang.reflect.Method;
import java.util.Random;
import org.obicere.cc.executor.Result;
import org.obicere.cc.tasks.projects.Runner;
public class CanReachRunner extends Runner {
@Override
public Result[] getResults(Class<?> clazz) {
try {
final Method method = clazz.getMethod("canReach", int.class, int.class, int.class);
final Random ran = new Random();
final Result[] results = new Result[10];
for (int i = 0; i < 10; i++) {
final int small = ran.nextInt(5) + 5;
final int large = ran.nextInt(5);
final int goal = (small + large * 5) + 5 + ran.nextInt(6);
results[i] = new Result(method.invoke(clazz.newInstance(), small, large, goal), (goal <= small + large * 5) && goal % 5 <= small, small, large, goal);
}
return results;
} catch (Exception e) {
return new Result[] {};
}
}
}