tags:

views:

985

answers:

3

Hello there. I have the following problem: I've deployed in Tomcat a JNLP and an executable JAR files. JNLP file should automatically download the JAR file and execute it. The JAR file is signed and verified. This is done (the downloading part). But when to execute the JAR main class (specified in the JNLP file), a problem occurs: A part of the main class code is executed. Afterwards, when it tries to load a class that has a static final org.apache.log4j.Logger instance declared, it says an error.

Below are the representative parts of the JNLP file, the code and the error.

JNLP

<?xml version='1.0' encoding='UTF-8'?>
<jnlp spec="1.5+" codebase="http://localhost:8080/examples" href="DemoInstaller.jnlp" download="eager" main="true">
    <information>
        <title>Demo Installer</title>
        <vendor>Codemart [www.codemart.ro]</vendor>
        <homepage>https://sourceforge.net/projects/cminstall/&lt;/homepage&gt;
        <description>This is a demo installer built using Codemart Installer framework with JavaFX</description>
        <description kind="tooltip">Codemart Demo Installer</description>
        <offline-allowed />
        <shortcut online="true">
            <desktop />
        </shortcut>
    </information>

<security>
    <all-permissions />
</security>

<update check="background" />

<resources>
    <j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" />
   <jar href="DemoInstaller.jar" main="true" download="eager" />
</resources>

<application-desc main-class="ro.codemart.installer.packer.ant.impl.nestedjar.Main" />

The main class:

public class Main {
 public static void main(String[] args) throws Exception {
     final Main main = new Main();
     //this is the problem class !
     Class clazz = Class.forName("WizardRunner");
     Method m = clazz.getMethod("main", new Class[]{args.getClass()});
     m.invoke(null, new Object[]{args});      
    ...
   }
}

And the problem class:

public class WizardRunner{

    private final static Logger log = Logger.getLogger(WizardRunner.class);
...
}

And the error:

log4j:ERROR Could not find [log4j.dtd]. Used [sun.misc.Launcher$AppClassLoader@d9f9c3] class loader in the search. log4j:ERROR Could not parse url [jar:http://localhost:8080/examples/DemoJar.jar!/log4j.xml]. java.io.FileNotFoundException: JAR entry log4j.dtd not found in at com.sun.jnlp.JNLPCachedJarURLConnection.connect(Unknown Source) at com.sun.jnlp.JNLPCachedJarURLConnection.getInputStream(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) at org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.java:612) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618) at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:470) at org.apache.log4j.LogManager.(LogManager.java:122) at org.apache.log4j.Logger.getLogger(Logger.java:117) at ro.codemart.installer.wizard.WizardRunner.(WizardRunner.java:38) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at ro.codemart.installer.packer.ant.impl.nestedjar.Main.executeApplicationMainClass(Main.java:216) at ro.codemart.installer.packer.ant.impl.nestedjar.Main.main(Main.java:290) 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) log4j:WARN No appenders could be found for logger (WizardRunner). log4j:WARN Please initialize the log4j system properly.

Thank you!

A: 

If you look in your stack trace the cause of the error is a FileNotFoundException for log4j.dtd. Look at how the DTD is referenced from your log4j.xml. Is the DTD included in your jar file? It needs to be in a place where the JVM can load it.

Mark
A: 

Yes, the log4j.dtd file comes embedded with log4j-1.2.12.jar. Also this log4j jar is in the classpath.

Flueras Bogdan
So you need to investigate why it cannot be loaded. Is the log4j jar within DemoInstaller.jar as it is not listed in the JNLP file.
Mark
The log4j.jar file is added dynamically to classpath at runtime, so no need to be listed in JNLP file. Also tried to add it to JNLP, but same error.
+1  A: 

I think the problem is missing log4j.jar - it's not specified or loaded by the .jnlp file. You mentioned in the previous answer that it's in your classpath, but how if you're running via WebStart? I believe your classpath is limited to what's defined in the .jnlp file.

Try adding

<jar href="log4j.jar" main="true" download="eager" />

to

<resources>
Greg Harman
Not totally true. I agree that log4j.jar is not defined in JNLP file, but this jar is added to classpath at runtime. If it were'nt so, I would get a ClassNotFoundException or something like that.Thank's for your suggestion, I've tried it, but still same err message!
So, that was the problem. Adding all my jars into the JNLP file under <resources> tag, like this <jar href="yourJar.jar">, but without main attribute