2

At present I'm getting errors about how it can't find one of my includes, specifically

java.lang.ClassNotFoundException: org.jivesoftware.smack.provider.ProviderManager

I have confirmed the file to be running as an executable jar, so I really don't know why it would error out like this, can someone provide me with some insight?

Here's what I'm currently doing, please correct me if any step of this is wrong.

  1. I take my (confirmed working) program, run it to double check.

  2. I right click the project > Export > Runnable jar file and Select the options > Package required libraries into generated jar file and export Ant Build script to file myProg.xml

    When myprog.xml comes out, it looks like this:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <project default="create_run_jar" name="Create Runnable Jar for Project myProg with Jar-in-Jar Loader">
    <!--this file was created by Eclipse Runnable JAR Export Wizard-->
    <!--ANT 1.7 is required                                        -->
    <target name="create_run_jar">
        <jar destfile="C:/Users/Dbell/Documents/EclipseProjects/myProg/myProg.jar">
            <manifest>
                <attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>
                <attribute name="Rsrc-Main-Class" value="com.myCom.noc.xmpptroubleshooter.Main"/>
                <attribute name="Class-Path" value="."/>
                <attribute name="Rsrc-Class-Path" value="./ httpasyncclient-4.0-beta2.jar httpcore-4.2.1.jar httpcore-nio-4.2.1.jar httpclient-4.2.1.jar commons-logging-1.1.1.jar commons-codec-1.6.jar log4j-1.2.12.jar logkit-1.0.1.jar avalon-framework-4.1.3.jar servlet-api-2.3.jar commons-net-3.1.jar xpp3_min-1.1.4c.jar NocLib-1.1.jar smack32-3.2.0.jar httpclient-3.1.jar"/>
            </manifest>
            <zipfileset src="jar-in-jar-loader.zip"/>
            <fileset dir="C:/Users/Dbell/Documents/EclipseProjects/myProg/bin"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\org.apache.httpcomponents\httpasyncclient\jars" includes="httpasyncclient-4.0-beta2.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\org.apache.httpcomponents\httpcore\jars" includes="httpcore-4.2.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\org.apache.httpcomponents\httpcore-nio\jars" includes="httpcore-nio-4.2.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\org.apache.httpcomponents\httpclient\jars" includes="httpclient-4.2.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\commons-logging\commons-logging\jars" includes="commons-logging-1.1.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\commons-codec\commons-codec\jars" includes="commons-codec-1.6.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\log4j\log4j\jars" includes="log4j-1.2.12.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\logkit\logkit\jars" includes="logkit-1.0.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\avalon-framework\avalon-framework\jars" includes="avalon-framework-4.1.3.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\javax.servlet\servlet-api\jars" includes="servlet-api-2.3.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\commons-net\commons-net\jars" includes="commons-net-3.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\xpp3\xpp3_min\jars" includes="xpp3_min-1.1.4c.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\com.MyCom\NocLib\jars" includes="NocLib-1.1.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\com.MyCom\smack32\jars" includes="smack32-3.2.0.jar"/>
            <zipfileset dir="C:\Users\Dbell\.ivy2\cache\com.apache\httpclient\jars" includes="httpclient-3.1.jar"/>
        </jar>
      <signjar jar="myProg.jar" alias="myAlias" keystore="path/to/myKs.ks" storepass="MyPass"/>
    </target>
    </project>
    
  3. From there I right click > run as > ant build file to sign my jar.

  4. Then I move it to my webserver where a launch.jnlp file exists. That looks like this:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <jnlp codebase="http://myServer:8080/myProg/" href="http://myServer:8080/myProg/launch.jnlp" spec="6.0+">
      <information>
          <title>myProg</title>
          <vendor>myName</vendor>
          <homepage href="http://myServer:8080/myProg/"/>
          <description>myProg</description>
          <description kind="short">myProg</description>
    
    
      </information>
      <security>
        <all-permissions/>
      </security>
      <resources>
          <j2se version="1.6+" />
          <jar href="myProg.jar" main="true"/>
      </resources>
      <application-desc main-class="com.myCom.noc.pathToMain.Main">
    
      </application-desc>
    </jnlp>
    

Full stack trace from when application is launched:

java.lang.ClassNotFoundException: org.jivesoftware.smack.provider.ProviderManager
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.myCom.noc.xmpptroubleshooter.Main.main(Main.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(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)

And this is the inside of my jar This is what the inside of my jar looks like

Community
  • 1
  • 1
A_Elric
  • 3,508
  • 13
  • 52
  • 85
  • Thanks for the formatting help @jschoen – A_Elric Nov 30 '12 at 20:30
  • No problem, putting the question/problem at the top has worked better for me in the past to get a response. I think it tells people what problems to look for while they are reading the rest of the information provided. – Jacob Schoen Nov 30 '12 at 20:33
  • Yeah, most likely a good idea, this one has had me going for a few days now and I'm totally out of options. – A_Elric Nov 30 '12 at 20:35
  • is it possible to get more of the stackdump, usually when geting classnotfound in java-web-start app It is simply because it's not on the classpath, or it is being loaded by some mechanism that isnt 100% compliant with java-web-start – Aksel Willgert Dec 01 '12 at 06:43
  • I would be more than happy to do so, let me do that now. – A_Elric Dec 01 '12 at 18:14
  • does one of those jars inside the big .jar include org.jivesoftware.smack.provider.ProviderManager ? because to me the stackdump looks like this is a missing class, not anything fishy with custom classloaders. – Aksel Willgert Dec 01 '12 at 19:12
  • 1
    Looks like some other people have problems when packing .jar inside other jars: http://stackoverflow.com/questions/10021715/weird-behavior-when-loading-jar-inside-a-jar-in-java-web-start – Aksel Willgert Dec 01 '12 at 19:25
  • @AkselWillgert Yes, Org.jivesoftware.smack.provider.ProviderManager() is inside of Smack32-3.2.0.jar if I recall correctly. – A_Elric Dec 01 '12 at 22:35
  • @AkselWillgert Good call on the linked thread. – Andrew Thompson Dec 03 '12 at 02:36
  • Thanks, for converting it to a proper answer, I wouldnt have been able to do so – Aksel Willgert Dec 03 '12 at 05:37

1 Answers1

2

As alluded by @AkselWillgert the standard Java class-loaders will not load classes from Jars inside other Jars. It will be necessary to do one of:

  1. Add a reference to each Jar in the resources section of the JNLP. Or in fact, we can go further and put commonly used APIs into extensions that can be used by many apps., E.G. a commons-logging.jnlp or jive.jnlp.
  2. Extract the classes from all Jars and add them into one single Jar. This is commonly against the user agreement of the API, destroys digital signatures and useful manifest information as might be expressed in a Service Provider Interface.
  3. Install a class-loader that can read Jar inside Jars. That would require a trusted app.

For a variety of reasons, the first is the best option.


.. how would I go about signing all those jars?

Consulting the docs for the signjar task would suggest something like (copy/pasted):

<signjar
    alias="testonly" keystore="testkeystore"
    storepass="apacheant"
    lazy="true"
    >
  <path>
    <fileset dir="dist" includes="**/*.jar" />
  </path>
</signjar>

Warning

Some of the Jars might already be digitally signed. If so, it is best to leave the original signature. How to do that, is more a question about the build tool.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433