0

I'm trying to make an applet with jPCT. Using jPCT requires that the jPCT jar be added to the classpath. I thought I had it, but I'm still getting a class not found exception about one of jPCT's classes.

My commands:

$ javac -classpath /var/www/html/jpct.jar:.  /var/www/html/HelloWorld.java
$ jar cf /var/www/html/HelloWorld.jar /var/www/html/HelloWorld.class

My HTML:

<html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
        <applet code="HelloWorld"
              width=640
              height=480
              archive="http://applet/HelloWorld.jar,http://applet/jpct.jar">
        </applet>
    </body>
</html>

I'm using Apache and I have verified that my jars are downloadable from the URLs in my code.

The exact error message:

$ firefox http://applet/HelloWorld.html
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1)
OpenJDK Server VM (build 20.0-b11, mixed mode)

(firefox-bin:15296): LIBDBUSMENU-GTK-CRITICAL **: dbusmenu_menuitem_property_set_shortcut: assertion `gtk_accelerator_valid(key, modifier)' failed
Unable to use Firefox's proxy settings. Using "DIRECT" as proxy type.
java.lang.NoClassDefFoundError: com/threed/jpct/World
    at HelloWorld.init(HelloWorld.java:18)
    at sun.applet.AppletPanel.run(AppletPanel.java:436)
    at net.sourceforge.jnlp.NetxPanel.run(NetxPanel.java:69)
    at java.lang.Thread.run(Thread.java:679)
Caused by: java.lang.ClassNotFoundException: com.threed.jpct.World
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader$CodeBaseClassLoader.findClass(JNLPClassLoader.java:1348)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    ... 4 more
Exception in thread "TimerQueue" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:155)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1262)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:459)
    at java.util.concurrent.DelayQueue.take(DelayQueue.java:205)
    at javax.swing.TimerQueue.run(TimerQueue.java:167)
    at java.lang.Thread.run(Thread.java:679)

What am I doing wrong?

John
  • 15,418
  • 12
  • 44
  • 65
  • Please show whole error message when running javac – bbaja42 Jun 20 '11 at 19:20
  • @bba There is no error message when running javac. The only error message is produced in the terminal I run firefox in when I open the page. I have posted it. – John Jun 20 '11 at 19:22
  • I doubt your machine host name that is serving this is `applet`, try `localhost` instead –  Jun 20 '11 at 22:03
  • @Jarrod Amahi gave me a ... *unique* DHCP setup. I put the applet name into the Amahi control panel as "applet" so it said to put "applet" in the address bar to get to it. My server is a different machine than my dev box, so localhost wouldn't work (I tried in on my server anyway, no go), but I *am* being served my HTML file from Apache on my server. – John Jun 20 '11 at 22:23
  • @Jarrod Wait, now it's working! I guess I had a caching issue also.... Thank you very much! – John Jun 20 '11 at 22:23

2 Answers2

1

You have to put your dependencies on the same web server that is serving the Applet .jar file and give the locations either absolutely or relative to the root context of the Applet.

And you have to load your Applet into your web browser from the web server, not from the file system.

Here is the relevant reading materials.

ARCHIVE = archiveList

This OPTIONAL attribute describes one or more archives containing classes and other resources that will be "preloaded". The classes are loaded using an instance of an AppletClassLoader with the given CODEBASE. The archives in archiveList are separated by ",". NB: in JDK1.1, multiple APPLET tags with the same CODEBASE share the same instance of a ClassLoader. This is used by some client code to implement inter-applet communication. Future JDKs may provide other mechanisms for inter-applet communication. For security reasons, the applet's class loader can read only from the same codebase from which the applet was started. This means that archives in archiveList must be in the same directory as, or in a subdirectory of, the codebase. Entries in archiveList of the form ../a/b.jar will not work unless explicitly allowed for in the security policy file (except in the case of an http codebase, where archives in archiveList must be from the same host as the codebase, but can have ".."'s in their paths.)

if your applet is at /var/www/html/Applet.jar then the simplest thing to do is put your dependencies in the exact same location /var/www/html/jcpt.jar and then you can just refer to it without having to worry about calculating the relative path.

Example

    <applet code="HelloWorld"
          width=640
          height=480
          archive="HelloWorld.jar,jpct.jar">
    </applet>
  • They are in the same dir, my `` code matches your example, "View Source" verifies that I am being served my HTML correctly, but I am still getting the same error. I know it's finding the jars, because when it wasn't, before I asked this question, it was giving warnings that it couldn't find them. Those are gone, but my error remains. – John Jun 20 '11 at 21:59
  • Well it turns out it was only working because I switched machines. At least that means it's client side and not a problem with my code. I guess I might try SU next. Thank you for your help. – John Jun 21 '11 at 02:35
-2

Have you used any server like Tomcat ? If you have, you may need to assign the path of your jar file to it or copy the jpct.jar to the tomcat/lib/ dir .

Ethan Zhong
  • 91
  • 1
  • 2
  • as a general rule you should never have to put `.jar` files in the `lib` directory in Tomcat, they should go in `WEB-INF/lib`, there are exceptions but they are very few and far between. –  Jun 20 '11 at 02:34
  • okay~I have to say you r precise, then we should write the path of jpct.jar file to the server.xml under tomcat/conf dir, right? – Ethan Zhong Jun 20 '11 at 07:51
  • 1
    you should never had to exit any Tomcat specific files or put any files in Tomcat specific directories as a general rule, everything should go in the `.war` –  Jun 20 '11 at 14:32
  • Until I'm ready, I'm not using any server. It's all local, so for now I am just opening my HTML file in FireFox. – John Jun 20 '11 at 14:36
  • @John the applet needs to know where to load the dependencies from and it must be the *server* that is serving the applet for security reasons. You can serve your html and `.jar` files from any web server, but they must come from a server for the applet security model to be able to find them. –  Jun 20 '11 at 19:41
  • @John you serve up dependencies to applets just like any other file from a file server, it should be accessible from a URL just like an image, html or javascript file would be. You don't need tomcat, apache or any other webserver will do. –  Jun 20 '11 at 19:48
  • @JarrodRoberson I have put the files on Apache, changed my `archive` line to point to my jars, verified that the files are downloadable from another machine, and I still get the same error... – John Jun 20 '11 at 21:06
  • @John you have to post what you have done for anyone to verify that it is correct, update your question with the changes you have made that you mention here. –  Jun 20 '11 at 21:26
  • @John see my answer, I doubt the name of your machine is `applet`. –  Jun 20 '11 at 21:38