[转_CLASSPATH] GlassFish 3.1.1 的JMS 独立客户端编程

下面文章很长,至于我的最终解决方法是 在 独立客户端的项目上右键->库->添加JAR/Folder

加入 C:\Program Files\glassfish-3.1.2\glassfish\lib\gf-client.jar 文件

 

 

最近一直在关注JMS,起因是从Magento 的PHP系统向JMS发送消息。实验了ActiveMQ,GlassFish与ActiveMQ的集成。最后还是觉得直接用GlassFish自带的OpenMQ省事。GlassFish 3 开始集成了对Stomp的支持,使得PHP系统与Java的系统能够很好的结合了。


      GlassFish升到3了,其JMS的使用有些变化,主要是使用的那些java库发生了变化。网上有很多很多人遇到问题,可是却很难很难找到答案。前段时间弄了一下PHP与JMS,也在GlassFish上写了消息接收和发送程序,本以为客户端程序又是java,应该是小儿科,结果昨天测试的时候才发现问题多多。

首先、对于GlassFish 3.1.1 独立的java程序需要添加的包有两个,一个是GlassFish的客户端:/home/tlz/glassfish3/glassfish/lib/gf-client.jar
另外一个是 /home/tlz/glassfish3/mq/lib/jms.jar。就这两个就够了,网上那些包含了很多包的程序,可能是针对glassfish 2.1的。有个外国网友骂到glassfish v3 越来越难用。

另外一个难点是JNDI的使用,几乎所有的错误都是出在jndi的lookup。其原因有两个:一种是缺乏运行时的包,另外一种可能是自己装了多个glassfish,把gf-client.jar包弄错了。

1、Glassfish的配置
假定在glassfish上配置了JNDI连接工厂jms/smsCF和一个Topic 配置:topic/SMSTopic,对应的物理地址为:SMSTopic。



2、发送代码

需要添加到库里的jar文件是:
./glassfish3/glassfish/lib/gf-client.jar
./glassfish3/mq/lib/jms.jar

package jmsclient;

import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JmsClient {

    public static void main(String[] args) {


        ConnectionFactory connectionFactory = null;
        Connection connection = null;
        Session session = null;
        // Queue queue = null;
        Topic topic = null;
        MessageProducer messageProducer = null;
        MapMessage message = null;
        TextMessage tm = null;



        try {
            Properties props = new Properties();


            props.setProperty("org.omg.CORBA.ORBInitialHost", "172.24.9.116");

            // optional.   Defaults to 3700.   Only needed if target orb port is not 3700.
            props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

            InitialContext context = new InitialContext(props);
            Object abcd = context.lookup("jms/smsCF");
            connectionFactory = (ConnectionFactory) context.lookup("jms/smsCF");

            topic = (Topic) context.lookup("topic/SMSTopic");

            connection = connectionFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            messageProducer = session.createProducer(topic);
            tm = session.createTextMessage();

            tm.setText("Hello,this is standnone jms client" + new Date());
            messageProducer.send(tm);



            connection.close();

        } catch (NamingException e) {
            Logger.getLogger(JmsClient.class.getName()).log(Level.SEVERE, null, e);
        } catch (JMSException e) {
            Logger.getLogger(JmsClient.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            System.out.println("ENDED.");
            System.exit(0);
        }


    }
}

上面这段代码说明,用队列也是可以向Topic发送消息的。

2、独立的远程接收代码

通过使用MessageListener接口,可以实现类是容器的OnMessage事件触发,用户只要编写实现OnMessage部分即可。
package jmslistener;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import jms.scnjw.gov.cn.ScnjwMessageListener;

public class JmsListener {

   
    public static void main(String[] args) {


        String jndiConnetionFactory = "jms/smsCF";
        String jndiDestName = "topic/SMSTopic";

        TopicConnectionFactory connectionFactory = null;
        TopicConnection connection = null;
        TopicSession session = null;
        // Queue queue = null;
        Topic topic = null;
        MessageProducer messageProducer = null;
        MapMessage message = null;
        TextMessage tm = null;



        try {
            Properties props = new Properties();
 
            props.setProperty("org.omg.CORBA.ORBInitialHost", "172.24.9.116");
            // optional.   Defaults to 3700.   Only needed if target orb port is not 3700.
            props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
            InitialContext context = new InitialContext(props);
            Object abcd = context.lookup("jms/smsCF");
            connectionFactory = (TopicConnectionFactory) context.lookup(jndiConnetionFactory);


            topic = (Topic) context.lookup(jndiDestName);
            connection = connectionFactory.createTopicConnection();
            session = (TopicSession) connection.createSession(
                    false, Session.AUTO_ACKNOWLEDGE);
             

            TopicSubscriber topicSubscriber = session.createSubscriber(topic);
            //设置Listener
            topicSubscriber.setMessageListener(new ScnjwMessageListener());
            connection.start();
            //一直监听消息直到按Q键推出。

            System.out.println("To end program, enter Q or q, "
                    + "then <return>");
            InputStreamReader inputStreamReader = new InputStreamReader(System.in);
            char answer = '\0';
            while (!((answer == 'q') || (answer == 'Q'))) {
                try {
                    answer = (char) inputStreamReader.read();
                } catch (IOException e) {
                    System.out.println("I/O exception: "
                            + e.toString());
                }
            }

            connection.close();

        } catch (NamingException e) {
            Logger.getLogger(JmsListener.class.getName()).log(Level.SEVERE, null, e);
        } catch (JMSException e) {
            Logger.getLogger(JmsListener.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            System.out.println("ENDED.");
            System.exit(0);
        }


    }
}

再建一个ScnjwMessageListener的类用于处理消息:
package jms.scnjw.gov.cn;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class ScnjwMessageListener implements MessageListener {

    @Override
    public void onMessage(Message msg) {
        try {
            System.out.print("receive msg from topic:");
            if (msg instanceof TextMessage) {

                System.out.println(((TextMessage) msg).getText());

            }
        } catch (JMSException ex) {
            Logger.getLogger(ScnjwMessageListener.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}


需要添加的库还是:
./glassfish3/glassfish/lib/gf-client.jar
./glassfish3/mq/lib/jms.jar

上述程序运行以后,就会一直不停的监听消息,一旦有消息到达就会自动调用Listener的onMessage方法。
这是运行结果:
run:
2011-8-31 10:42:11 com.sun.enterprise.v3.server.CommonClassLoaderService Impl findDerbyClient
信息: Cannot find javadb client jar file, derby jdbc driver will not be available by default.
2011-8-31 10:42:17 org.hibernate.validator.util.Version <clinit>
信息: Hibernate Validator 4.1.0.Final
2011-8-31 10:42:17 org.hibernate.validator.engine.resolver.DefaultTraversableResolv er detectJPA
信息: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
2011-8-31 10:42:17 com.sun.messaging.jms.ra.ResourceAdapter start
信息: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter: 版本:   4.5.1   (Build 3-b) 编译:   Tue Jun 21 16:31:32 PDT 2011
2011-8-31 10:42:17 com.sun.messaging.jms.ra.ResourceAdapter start
信息: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter starting: broker is REMOTE, connection mode is TCP
2011-8-31 10:42:17 com.sun.messaging.jms.ra.ResourceAdapter start
信息: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter Started:REMOTE
To end program, enter Q or q, then <return>
receive msg from topic:Hello,this is standnone jms clientWed Aug 31 10:42:36 CST 2011
receive msg from topic:Hello,this is standnone jms clientWed Aug 31 11:20:18 CST 2011
receive msg from topic:Hello,this is standnone jms clientWed Aug 31 11:22:06 CST 2011

3、如何独立运行上述程序


        用Netbeans 7.0.1开发,在开发环境下只需要上面的两个包文件即可。可一旦要独立运行,可能需要glassfish的很多很多的包,只要缺少一个就会出现如下错误:
[tlz@localhost dist]$ java -jar JmsClient.jar 
2011-8-31 11:29:50 jmsclient.JmsClient main
严重: null
javax.naming.NoInitialContextExceptio n: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:   java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at jmsclient.JmsClient.main(JmsClient.java:62)
ENDED.

昨天在家里,我把glassfish的所有jar包和mq下的所有包拷贝到JmsClient.jar所在目录下lib下,上面的命令就可以正常运行了。如果有有心人,再把那个目录下的jar包一个一个的删除,应该可以弄出个最小集合来的吧。也有老外说,查看gf-client.jar包的MANIFEST.MF文件,那里列出了需要的jar包。这是那个文件,太多了:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: Apache Maven
Archiver-Version: Plexus Archiver
Built-By: java_re
Build-Jdk: 1.6.0_10
Package: org.glassfish.appclient.client.acc
Main-Class: org.glassfish.appclient.client.AppClientFacade
GlassFish-ServerExcluded: true
PreMain-Class: org.glassfish.appclient.client.acc.agent.AppClientConta
  inerAgent
Class-Path: ../modules/jtype.jar ../modules/tools.jar ../modules/glass
  fish-corba-asm.jar ../modules/glassfish-corba-codegen.jar ../modules/
  glassfish-corba-csiv2-idl.jar ../modules/glassfish-corba-internal-api
  .jar ../modules/glassfish-corba-newtimer.jar ../modules/glassfish-cor
  ba-omgapi.jar ../modules/glassfish-corba-orb.jar ../modules/glassfish
  -corba-orbgeneric.jar ../modules/auto-depends.jar ../modules/config.j
  ar ../modules/config-types.jar ../modules/hk2.jar ../modules/hk2-core
  .jar ../modules/osgi-adapter.jar ../modules/grizzly-comet.jar ../modu
  les/grizzly-config.jar ../modules/grizzly-framework.jar ../modules/gr
  izzly-http.jar ../modules/grizzly-http-servlet.jar ../modules/grizzly
  -lzma.jar ../modules/grizzly-portunif.jar ../modules/grizzly-rcm.jar 
  ../modules/grizzly-utils.jar ../modules/grizzly-websockets.jar ../mod
  ules/javax.mail.jar ../modules/pkg-client.jar ../modules/jaxb-osgi.ja
  r ../modules/activation.jar ../modules/el-api.jar ../modules/jaxr-api
  -osgi.jar ../modules/jaxrpc-api-osgi.jar ../modules/endorsed/jaxb-api
  -osgi.jar ../modules/stax-api.jar ../modules/junit.jar ../modules/sta
  x2-api.jar ../modules/woodstox-core-asl.jar ../modules/javax.persiste
  nce.jar ../modules/org.eclipse.persistence.antlr.jar ../modules/org.e
  clipse.persistence.asm.jar ../modules/org.eclipse.persistence.core.ja
  r ../modules/org.eclipse.persistence.jpa.jar ../modules/org.eclipse.p
  ersistence.jpa.modelgen.jar ../modules/org.eclipse.persistence.oracle
  .jar ../modules/endorsed/javax.annotation.jar ../modules/javax.ejb.ja
  r ../modules/javax.enterprise.deploy.jar ../modules/javax.jms.jar ../
  modules/javax.management.j2ee.jar ../modules/javax.resource.jar ../mo
  dules/javax.security.auth.message.jar ../modules/javax.security.jacc.
  jar ../modules/javax.servlet.jar ../modules/javax.servlet.jsp.jar ../
  modules/javax.transaction.jar ../modules/simple-glassfish-api.jar ../
  modules/admin-core.jar ../modules/admin-util.jar ../modules/config-ap
  i.jar ../modules/monitoring-core.jar ../modules/acc-config.jar ../mod
  ules/gf-client-module.jar ../modules/gms-bootstrap.jar ../modules/amx
  -core.jar ../modules/amx-j2ee.jar ../modules/annotation-framework.jar
  ../modules/common-util.jar ../modules/container-common.jar ../module
  s/glassfish-api.jar ../modules/glassfish-ee-api.jar ../modules/glassf
  ish-naming.jar ../modules/internal-api.jar ../modules/scattered-archi
  ve-api.jar ../modules/stats77.jar ../modules/connectors-inbound-runti
  me.jar ../modules/connectors-internal-api.jar ../modules/connectors-r
  untime.jar ../modules/work-management.jar ../modules/glassfish.jar ..
  /modules/kernel.jar ../modules/logging.jar ../modules/deployment-comm
  on.jar ../modules/deployment-javaee-core.jar ../modules/dol.jar ../mo
  dules/ejb-container.jar ../modules/ejb-internal-api.jar ../modules/ld
  apbp-repackaged.jar ../modules/libpam4j-repackaged.jar ../modules/man
  agement-api.jar ../modules/flashlight-framework.jar ../modules/gmbal.
  jar ../modules/ha-api.jar ../modules/class-model.jar ../modules/asm-a
  ll-repackaged.jar ../modules/bean-validator.jar ../modules/jms-core.j
  ar ../modules/endorsed/webservices-api-osgi.jar ../modules/webservice
  s-extra-jdk-packages.jar ../modules/webservices-osgi.jar ../modules/o
  rb-connector.jar ../modules/orb-iiop.jar ../modules/eclipselink-wrapp
  er.pom ../modules/jpa-connector.jar ../modules/persistence-common.jar
  ../modules/cmp-internal-api.jar ../modules/appclient.security.jar ..
  /modules/ejb.security.jar ../modules/jaspic.provider.framework.jar ..
  /modules/security.jar ../modules/ssl-impl.jar ../modules/websecurity.
  jar ../modules/webservices.security.jar ../modules/jta.jar ../modules
  /jts.jar ../modules/transaction-internal-api.jar ../modules/el-impl.j
  ar ../modules/jsp-impl.jar ../modules/war-util.jar ../modules/web-cli
  .jar ../modules/web-core.jar ../modules/web-embed-api.jar ../modules/
  web-glue.jar ../modules/web-gui-plugin-common.jar ../modules/web-nami
  ng.jar ../modules/jsr109-impl.jar ../modules/mimepull.jar ../modules/
  tiger-types.jar ../modules/shoal-gms-api.jar http://www.cnblogs.com/mq/lib/imq.jar ../
  ../mq/lib/imqadmin.jar http://www.cnblogs.com/mq/lib/imqutil.jar http://www.cnblogs.com/mq/lib/fscontex
  t.jar ../lib/install/applications/jmsra/imqjmsra.jar ../lib/install/a
  pplications/__ds_jdbc_ra/__ds_jdbc_ra.jar ../lib/install/applications
  /__cp_jdbc_ra/__cp_jdbc_ra.jar ../lib/install/applications/__xa_jdbc_
  ra/__xa_jdbc_ra.jar ../lib/install/applications/__dm_jdbc_ra/__dm_jdb
  c_ra.jar http://www.cnblogs.com/javadb/lib/derby.jar http://www.cnblogs.com/javadb/lib/derbyclient.jar 
  http://www.cnblogs.com/javadb/lib/derbynet.jar http://www.cnblogs.com/javadb/lib/derbytools.jar http://www.cnblogs.com/j
  avadb/lib/derbyrun.jar ../lib/install/applications/jaxr-ra/jaxr-ra.ja
  r ../modules/aixporting-repackaged.jar
GlassFish-Conditional-Additions: ../modules/aixporting-repackaged.jar

看起来很痛苦,不过,能够摆脱glassfish那个大家伙的控制,把客户端考到任何机器上都能运行,这也还是值得的。

4、一位外国朋友给出的独立客户端需要的jar包列表
auto-depends.jar
deployment-common.jar
glassfish-corba-internal-api.jar    
internal-api.jar
management-api.jar
bean-validator.jar
dol.jar
glassfish-corba-newtimer.jar        
javax.ejb.jar
orb-connector.jar
common-util.jar
ejb-container.jar
glassfish-corba-omgapi.jar      
javax.jms.jar
orb-iiop.jar
config-api.jar
ejb.security.jar
glassfish-corba-orb.jar
javax.resource.jar
security.jar
config-types.jar
glassfish-api.jar
glassfish-corba-orbgeneric.jar      
javax.servlet.jar
ssl-impl.jar
config.jar
glassfish-corba-asm.jar
glassfish-naming.jar
javax.transaction.jar
transaction-internal-api.jar
connectors-internal-api.jar      
glassfish-corba-codegen.jar      
gmbal.jar
jta.jar
container-common.jar
glassfish-corba-csiv2-idl.jar        
hk2-core.jar
kernel.jar
该文地址:http://stackoverflow.com/questions/4311157/glassfish-v3-x-and-remote-standalone-client

你可能感兴趣的:(Glassfish)