Почему моя программа Jnlp не работает с log4j?
У меня следующая проблема: я развернул в Tomcat JNLP и исполняемые файлы JAR. Файл JNLP должен автоматически загрузить файл JAR и выполнить его. Файл JAR подписан и проверен. Это сделано (часть загрузки). Но когда выполнить основной класс JAR (указанный в файле JNLP), возникает проблема: выполняется часть кода основного класса. После этого, когда он пытается загрузить класс с объявленным статическим конечным экземпляром org.apache.log4j.Logger, он сообщает об ошибке.
Ниже представлены типичные части файла JNLP, код и ошибка.
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/</homepage>
<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" />
Основной класс:
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});
...
}
}
И проблема класса:
public class WizardRunner{
private final static Logger log = Logger.getLogger(WizardRunner.class);
...
}
И ошибка:
log4j: ОШИБКА Не удалось найти [log4j.dtd]. В поиске использовался загрузчик классов [sun.misc.Launcher$AppClassLoader@d9f9c3]. log4j: ОШИБКА Не удалось проанализировать URL [jar: http://localhost:8080/examples/DemoJar.jar!/log4j.xml%5D. java.io.FileNotFoundException: запись JAR log4j.dtd не найдена в com.sun.jnlp.JNLPCachedJarURLConnection.connect(неизвестный источник) в com.sun.jnlp.JNLPCachedJarURLConnection.getInputStream(неизвестный источник) в com.sun.org.ap.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Неизвестный источник) по адресу com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ (Неизвестный источник) в com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Неизвестный источник) в com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ PrologDriver.next(Неизвестный Источник) на com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next (неизвестный источник) на com.sun.org.apache.xerces.internal.impl.X MLDocumentFragmentScannerImpl.scanDocument(неизвестный источник) по адресу com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(неизвестный источник) по адресу com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(неизвестный источник)) на com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(неизвестный источник) на com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(неизвестный источник) на com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(неизвестный источник) в javax.xml.parsers.DocumentBuilder.parse(неизвестный источник) в org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.jpg) в org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711) в org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618) в org.apache.log4j.verterO.selectAndConfigure(OptionConverter.java:470) в org.apache.log4j.LogManager.(LogManager.java:122) в org.apache.log4j.Logger.getLogger(Logger.java:117) в ro.codemart.installer.wizard.WizardRun (WizardRunner.java:38) на java.lang.Class.forName0(собственный метод) на java.lang.Class.forName(неизвестный источник) на ro.codemart.installer.packer.ant.impl.nestedjar.Main.executeApplicationMainClass(Main.java:216) в ro.codemart.installer.packer.ant.impl.nestedjar.Main.main(Main.java:290) в sun.reflect.NativeMethodAccessorImpl.invoke0(собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke(Неизвестный источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke(Неизвестный источник) в java.lang.reflect.Method.invoke(Неизвестный источник) в com.sun.javaws.Launcher.executeApplication Unknown.sun.javaws.Launcher.executeMainClass(неизвестный источник) на com.sun.javaws.Launcher.doLaunchApp(неизвестный источник) на com.sun.javaws.Launcher.run(неизвестный источник) на java.lang.Thread.run(неизвестный источник)) log4j: ПРЕДУПРЕЖДЕНИЕ Не удалось найти ни одного дополнительного устройства для ведения журнала (WizardRunner). log4j:WARN Пожалуйста, правильно инициализируйте систему log4j.
Спасибо!
3 ответа
Я думаю, что проблема отсутствует log4j.jar - он не указан или загружен файлом.jnlp. Вы упомянули в предыдущем ответе, что он находится в вашем classpath, но как, если вы работаете через WebStart? Я считаю, что ваш classpath ограничен тем, что определено в файле.jnlp.
Попробуйте добавить
<jar href="log4j.jar" main="true" download="eager" />
в
<resources>
Если вы просматриваете трассировку стека, причиной ошибки является исключение FileNotFoundException для log4j.dtd. Посмотрите, как на DTD ссылаются из вашего log4j.xml. DTD включен в ваш файл JAR? Это должно быть в месте, где JVM может загрузить это.
Да, файл log4j.dtd поставляется вместе с log4j-1.2.12.jar. Также этот jar log4j находится в пути к классам.