Search code examples
javajarexecutable-jarclassnotfoundexceptionjava-web-start

ClassNotFoundException for Java WebStart


I am trying to learn Java WebStart following THIS TUTORIAL, but I am running into a ClassNotFoundException. I deployed my jar file to https://dalayach.github.io/TestClass.jar

Here is the stacktrace

java.lang.ClassNotFoundException: testPackage.TestClass
    at java.net.URLClassLoader.findClass(Unknown Source)
    at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.sun.jnlp.JNLPClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
    at com.sun.javaws.Launcher.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Here is my TestClass.jnlp

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase=
"https://dalayach.github.io"
    href="TestClass.jnlp">
    <information>
        <title>TestClass Title</title>
        <vendor>TestClass Vendor</vendor>
    </information>
    <resources>
        <!-- Application Resources -->
        <j2se version="1.8+"
              href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="TestClass.jar"
            main="true" />

    </resources>
    <application-desc
         name="TestClass application-desc name"
         main-class=
        "testPackage.TestClass"
         width="300"
         height="300">
     </application-desc>
     <update check="background"/>
</jnlp>                                   

Here is my TestClass.java

package testPackage;

import javax.swing.JFrame;

public class TestClass
{

   public static void main(String[] args)
   {
   
      JFrame frame = new JFrame();
   
      frame.setTitle("TestClass JFrame title");
      frame.setSize(300, 300);
      frame.setLocation(300, 300);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
      frame.setVisible(true);
   
   }

}

Here is mymanifest.txt

Permissions: sandbox
Codebase: dalayach.github.io
Application-Name: TestClass
Main-Class: testPackage.TestClass

And finally, here is some relevant info

$ javac -version
javac 1.8.0_291

$ java -version
java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)

$ curl https://dalayach.github.io/TestClass.jnlp
/** It returned my up-to-date jnlp */

$ curl https://dalayach.github.io/TestClass.jar
/** same for jar */

$ curl https://dalayach.github.io/testPackage/TestClass.java
/** same for java */

$ javac testPackage/TestClass.java
/** this is how I compile my class */

$ jar cvfm TestClass.jar mymanifest.txt testPackage/
/** this is how I construct my jar file, per the instructions linked in the beginning */

$ java -jar TestClass.jar
/** my application successfully starts */

$ jar tvf TestClass.jar
     0 Sat May 29 16:46:46 EDT 2021 META-INF/
   185 Sat May 29 16:46:46 EDT 2021 META-INF/MANIFEST.MF
     0 Sat May 29 16:46:18 EDT 2021 testPackage/
   659 Sat May 29 16:46:32 EDT 2021 testPackage/TestClass.class
   385 Sat May 29 16:46:18 EDT 2021 testPackage/TestClass.java

And when I open the MANIFEST.MF, I see this.

Manifest-Version: 1.0
Application-Name: TestClass
Permissions: sandbox
Codebase: dalayach.github.io
Created-By: 1.8.0_291 (Oracle Corporation)
Main-Class: testPackage.TestClass

I've tried several variants of options for the .jnlp and the .java. You can see a full list of the things I tried HERE. Any ideas? It doesn't have to solve it, just any ideas to make progress would be helpful and appreciated! Thank you in advance.


Solution

  • Apparently, my code wasn't wrong, but I was making and testing changes so quickly that I was making updates faster than Java WebStart could check for them.

    This is because of the update policy I had above -- If you have <update check="background"/> as a setting in your .jnlp, you are telling Java WebStart to download the newest files lazily. This means that if you jump back and forth between different solutions rapidly, Java WebStart may literally be too slow to keep up, and have an out of date version by the time the old one finally comes in.

    There are 1 of 2 solutions to choose from.

    • Change the update policy for TestClass.jnlp.

      • If you want Java WebStart to wait until all updates have downloaded before trying to run your application, you should change your update policy to be something like this - <update check="always">. This way, you can guarantee that your jnlp is pulling the most recent files.
    • Use javaws -uninstall before each run of your application

      • This command clears the cache, so that your program needs to be redownloaded fresh. This is effectively the same result as the above bullet, but this allows you to keep your .jnlp file with the preferred settings. Plus, you don't have to keep switching it back and forth as you debug any settings. Simply clear the cache and test.