在运行时动态加载 Glassfish JMS jar 会抛出 NoClassDefFoundError javax/jms/Destination
loading Glassfish JMS jars dynamically at runtime throws a NoClassDefFoundError javax/jms/Destination
我在这个问题上被困了一段时间,非常希望得到任何帮助。
我的部分应用程序使用 Glassfish JMS 传输消息,如果包含 jar,应用程序在我的开发机器上运行顺利,现在我需要在运行时动态加载 JMS jar,所以我使用了以下代码在运行时 classloader 中加载 jar
public class ClassPathHack {
private static final Class<?>[] parameters = new Class[]{URL.class};
public static synchronized void addFile(String s) throws IOException, Exception {
File f = new File(s);
try {
java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
java.net.URL url = f.toURI().toURL();
for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
if (it.equals(url)){
return;
}
}
java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
method.setAccessible(true);
method.invoke(loader, new Object[]{url});
} catch (final java.lang.NoSuchMethodException |
java.lang.IllegalAccessException |
java.net.MalformedURLException |
java.lang.reflect.InvocationTargetException e){
throw new Exception(e);
}
}
}
并且在主要方法中,我已经加载了所有 JMS 使用的 jar,然后使用以下代码引发连接到 JMS 的线程:
public static void loadGlassfishJars(){
try {
System.out.println("DEBUGGNG: Loading Glassfish jars");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\appserv-rt.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\console-jms-plugin.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\gf-client.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\imq.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\imqbroker.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\install\applications\jmsra\imqjmsra.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\javaee.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jms-admin.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jms-core.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\jms.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jmxremote_optional-repackaged.jar");
} catch (Exception ex) {
Logger.getLogger(ZMQTranslator.class.getName()).log(Level.SEVERE, null, ex);
}
主要方法如下所示:
public static void main(String[] args) {
//loading glassfish jms jars
loadGlassfishJars();
//JMS connector thread
System.out.println("DEBUGGNG:initiating ZMQConnectionReceiver");
ZMQConnectionReceiver zmqCon = new ZMQConnectionReceiver();
Thread t = new Thread(zmqCon);
t.start();
}
在调用ZMQConnectionReceiver class的构造函数时抛出异常,它导入了以下classes
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
//NOT RELATED IMPORTS
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.json.Json;
import model.DeviceConnection;
import org.zeromq.ZMQ;
import javax.json.stream.*;
它有一个简单的构造函数如下:
public ZMQConnectionReceiver(){
lostNFound = new ConcurrentLinkedDeque();
}
调用构造函数时抛出异常
Exception in thread "main" java.lang.NoClassDefFoundError:
javax/jms/Destination
我已经在 jms.jar 中检查了目的地 Class 的存在,它就在那里。
注意。 Glassfish JMS 有一个奇怪的行为,它要求连接到它的应用程序安装的 JAR 应与您尝试连接的 Glassfish 版本相同,任何即使来自相同的 Glassfish 版本但其他安装,其他 jars 也会失败。
我该如何解决这个问题?
我设法通过添加以下依赖项下载所有 JMS 依赖项 JAR 来解决此问题
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
</dependency>
到 maven 应用程序的 pom 文件并构建应用程序。
之后,我将下载的 JAR 包含在我的应用程序中,它作为独立应用程序在任何机器上都运行良好。
我在这个问题上被困了一段时间,非常希望得到任何帮助。
我的部分应用程序使用 Glassfish JMS 传输消息,如果包含 jar,应用程序在我的开发机器上运行顺利,现在我需要在运行时动态加载 JMS jar,所以我使用了以下代码在运行时 classloader 中加载 jar
public class ClassPathHack {
private static final Class<?>[] parameters = new Class[]{URL.class};
public static synchronized void addFile(String s) throws IOException, Exception {
File f = new File(s);
try {
java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
java.net.URL url = f.toURI().toURL();
for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
if (it.equals(url)){
return;
}
}
java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
method.setAccessible(true);
method.invoke(loader, new Object[]{url});
} catch (final java.lang.NoSuchMethodException |
java.lang.IllegalAccessException |
java.net.MalformedURLException |
java.lang.reflect.InvocationTargetException e){
throw new Exception(e);
}
}
}
并且在主要方法中,我已经加载了所有 JMS 使用的 jar,然后使用以下代码引发连接到 JMS 的线程:
public static void loadGlassfishJars(){
try {
System.out.println("DEBUGGNG: Loading Glassfish jars");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\appserv-rt.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\console-jms-plugin.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\gf-client.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\imq.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\imqbroker.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\install\applications\jmsra\imqjmsra.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\lib\javaee.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jms-admin.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jms-core.jar");
ClassPathHack.addFile(glassfishPath + "\mq\lib\jms.jar");
ClassPathHack.addFile(glassfishPath + "\glassfish\modules\jmxremote_optional-repackaged.jar");
} catch (Exception ex) {
Logger.getLogger(ZMQTranslator.class.getName()).log(Level.SEVERE, null, ex);
}
主要方法如下所示:
public static void main(String[] args) {
//loading glassfish jms jars
loadGlassfishJars();
//JMS connector thread
System.out.println("DEBUGGNG:initiating ZMQConnectionReceiver");
ZMQConnectionReceiver zmqCon = new ZMQConnectionReceiver();
Thread t = new Thread(zmqCon);
t.start();
}
在调用ZMQConnectionReceiver class的构造函数时抛出异常,它导入了以下classes
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
//NOT RELATED IMPORTS
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.json.Json;
import model.DeviceConnection;
import org.zeromq.ZMQ;
import javax.json.stream.*;
它有一个简单的构造函数如下:
public ZMQConnectionReceiver(){
lostNFound = new ConcurrentLinkedDeque();
}
调用构造函数时抛出异常
Exception in thread "main" java.lang.NoClassDefFoundError: javax/jms/Destination
我已经在 jms.jar 中检查了目的地 Class 的存在,它就在那里。
注意。 Glassfish JMS 有一个奇怪的行为,它要求连接到它的应用程序安装的 JAR 应与您尝试连接的 Glassfish 版本相同,任何即使来自相同的 Glassfish 版本但其他安装,其他 jars 也会失败。
我该如何解决这个问题?
我设法通过添加以下依赖项下载所有 JMS 依赖项 JAR 来解决此问题
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
</dependency>
到 maven 应用程序的 pom 文件并构建应用程序。
之后,我将下载的 JAR 包含在我的应用程序中,它作为独立应用程序在任何机器上都运行良好。