【问题标题】:loading Glassfish JMS jars dynamically at runtime throws a NoClassDefFoundError javax/jms/Destination在运行时动态加载 Glassfish JMS jar 会引发 NoClassDefFoundError javax/jms/Destination
【发布时间】:2015-08-17 22:35:24
【问题描述】:

我急需在这个问题上的任何帮助,因为我现在被困了一段时间。

我的应用程序的一部分使用 Glassfish JMS 传输消息,如果包含 jars,应用程序在我的开发机器上运行顺利,现在我需要在运行时动态加载 JMS jars,所以我使用以下代码加载运行时类加载器中的 jars

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);
        }
    }
}

在 main 方法中,我已经加载了所有 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类的构造函数时抛出异常,该类导入如下类

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();
    }

调用构造函数时抛出异常

线程“主”java.lang.NoClassDefFoundError 中的异常: javax/jms/目标

我在 jms.jar 中检查了 Destination Class 的存在,它就在那里。

注意。 Glassfish JMS 有一个奇怪的行为,它要求连接到它的应用程序安装的 JAR 必须与您尝试连接的 Glassfish 版本相同,否则任何其他 jar 都会失败如果它来自相同的 Glassfish 版本但其他安装。

我该如何解决这个问题?

【问题讨论】:

    标签: java multithreading reflection glassfish jms


    【解决方案1】:

    我设法通过添加以下依赖项下载所有 JMS 依赖项 JAR 来解决此问题

    <dependency>
        <groupId>org.glassfish.main.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>3.1.2</version>
    </dependency>
    

    到 maven 应用程序的 pom 文件并构建应用程序。

    之后,我将下载的 JAR 包含在我的应用程序中,它可以在任何机器上作为独立应用程序正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2012-07-08
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      相关资源
      最近更新 更多