java.lang.ClassNotFoundException:试图启动windows服务时的org.zeromq.Z



我创建了一个基本的Maven java应用程序,它依赖于JeroMQ,这是ZeroMQ的完整java实现。由于我还需要将这个java应用程序包装为一个windows服务,所以我选择使用Apache Commons Daemon,特别是下面的示例:http://web.archive.org/web/20090228071059/http://blog.platinumsolutions.com/node/234以下是Java代码的样子:

package com.org.SubscriberACD;
import java.nio.charset.Charset;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Socket;
/**
 * JeroMQ Subscriber for Apache Commons Daemon
 *
 */
public class Subscriber 
{
    /**
    * Single static instance of the service class
    */
    private static Subscriber subscriber_service = new Subscriber();
    /**
     * Static method called by prunsrv to start/stop
     * the service.  Pass the argument "start"
     * to start the service, and pass "stop" to
     * stop the service.
     */
    public static void windowsService(String args[]) {
       String cmd = "start";
       if(args.length > 0) {
          cmd = args[0];
       }
       if("start".equals(cmd)) {
          subscriber_service.start();
       }
       else {
          subscriber_service.stop();
       }
    }
    /**
     * Flag to know if this service
     * instance has been stopped.
     */
    private boolean stopped = false;

    /**
     * Start this service instance
     */
    public void start() {
       stopped = false;
       System.out.println("My Service Started "
                          + new java.util.Date());
       ZContext context = new ZContext();
       Socket subscriber = context.createSocket(ZMQ.SUB);
       subscriber.connect("tcp://localhost:5556");
       String subscription = "MySub";
       subscriber.subscribe(subscription.getBytes(Charset.forName("UTF-8")));
       while(!stopped) {
          System.out.println("My Service Executing "
                              + new java.util.Date());
          String topic = subscriber.recvStr();
          if (topic == null)
              break;
          String data = subscriber.recvStr();
          assert(topic.equals(subscription));
          System.out.println(data);
          synchronized(this) {
             try {
                this.wait(60000);  // wait 1 minute
             }
             catch(InterruptedException ie){}
          }
       }
       subscriber.close();
       context.close();
       context.destroy();
       System.out.println("My Service Finished "
                           + new java.util.Date());
    }
    /**
     * Stop this service instance
     */
    public void stop() {
       stopped = true;
       synchronized(this) {
          this.notify();
       }
    }
 }

然后我创建了如下文件夹结构,就像教程建议的那样:

E:SubscriberACD
   bin
        subscriberACD.exe
        subscriberACDw.exe
   classes
        comorgSubscriberACDSubscriber.class
   logs

然后我导航到bin目录,并发出以下命令来安装服务:

subscriberACD.exe //IS//SubscriberACD --Install=E:SubscriberACDbinsubscriberACD.exe --Descriptio
n="Subscriber using Apache Commons Daemon" --Jvm=c:glassfish4jdk7jre
binserverjvm.dll --Classpath=E:SubscriberACDclasses --StartMode=jvm
 --StartClass=com.org.SubscriberACD.Subscriber --StartMethod=windowsSer
vice --StartParams=start --StopMode=jvm --StopClass=com.org.SubscriberA
CD.Subscriber --StopMethod=windowsService --StopParams=stop --LogPath=E:SubscriberACDlogs --StdOutput=auto --StdError=auto

安装工作正常,因为我可以在Windows服务中看到它。然而,当我尝试从那里启动它时,我收到一个错误,说"Windows无法在本地计算机上启动SubscriberACD"。

我检查了错误日志,看到了以下条目:

2016-04-14 14:38:40 Commons Daemon procrun stderr initialized
Exception in thread "main" ror: org/zeromq/ZContext
    at com.org.SubscriberACD.Subscriber.start(Subscriber.java:57)
    at com.org.SubscriberACD.Subscriber.windowsService(Subscriber.java:33)
Caused by: java.lang.ClassNotFoundException: org.zeromq.ZContext
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 2 more

值得注意的是,JeroMQ目前是我的Maven依赖项下的一个jar。我从我的POM.xml文件中配置了它。

我认为问题可能是我的服务无法访问我的Maven依赖项下的JeroMQ jar。我的假设是类文件不包含依赖项。所以我试着把我的整个项目导出为一个罐子,并把那个婴儿放在E:SubscriberACDclasses下所以我的结构现在看起来是这样的:

E:SubscriberACD
   bin
        subscriberACD.exe
        subscriberACDw.exe
   classes
        comorgSubscriberACD
             Subscriber.class
        Subscriber.jar
   logs

然而,这并没有解决问题。有人能解释一下吗?

将--Classpath参数更改为:

--Classpath=E:SubscriberACDclassesyour-jar-filename.jar 

几乎可以肯定,您还需要其他jarfiles,所以只需使用将它们附加到--Classpath的末尾;(分号)分隔符。。。

--Classpath=E:SubscriberACDclassesyour-jar-filename.jar;e:other-dirclassessome-other.jar;etc...

相关内容

最新更新