2013-04-14 5 views
1

저는 MDB 및 EE에서 새로 왔습니다. 내가 틀렸다고 말해줘. 내 응용 프로그램이 Websphere MQ와 상호 작용해야합니다 (대기열에있는 메시지를 기다리고 뭔가를 수행하고 회신). NetBeans 7.3, GlassFish 3.1, Websphere MQ 6.2, resorce adapter wmq.jmsra.rar를 사용하고 있습니다. 상호 작용은 웹 MQ 특성 인 jms 형식이 아니어야합니다. 어댑터를 배포하고 Connecton 풀 및 관리 객체를 만듭니다. domain.xml의Mdb Glasswish Websphere MQ

넷빈즈에서
<connector-connection-pool description="" name="cpMqAdapter" resource-adapter-name="wmq.jmsra" connection-definition-name="javax.jms.QueueConnectionFactory" transaction-support="LocalTransaction"> 
    <property name="port" value="1414"></property> 
    <property name="CCSID" value="866"></property> 
    <property name="hostName" value="192.168.0.11"></property> 
    <property name="queueManager" value="QM"></property> 
    <property name="channel" value="SrvConn"></property> 
    <property description="CLIENT - mq on other computer" name="transportType" value="CLIENT"></property> 
</connector-connection-pool> 


<admin-object-resource enabled="false" res-adapter="wmq.jmsra" res-type="javax.jms.Queue" description="" jndi-name="wmqJmsAOR" class-name="com.ibm.mq.connector.outbound.MQQueueProxy"> 
    <property name="priority" value="APP"></property> 
    <property name="failIfQuiesce" value="true"></property> 
    <property name="baseQueueManagerName" value="QM"></property> 
    <property name="CCSID" value="1208"></property> 
    <property name="persistence" value="APP"></property> 
    <property name="encoding" value="NATIVE"></property> 
    <property name="baseQueueName" value="TEST"></property> 
    <property name="targetClient" value="MQ"></property> 
    <property name="expiry" value="APP"></property> 
</admin-object-resource> 

' 에서 은 내가 EE 프로젝트 및 메시지 구동 빈을 만들 수 있어요. 내가있어이 코드 '이 MDB는 큐 (내가 웹 스피어 MQ 콘솔에서 테스트 메시지를 넣을거야) listenig되지 않는 이유

@MessageDriven(mappedName = "wmqJmsAOR", activationConfig = { 
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto- 
    acknowledge"), 
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") 

}) 
public class NewMessage implements MessageListener { 
public NewMessage() { 
    super(); 
    System.out.println("I created"); 
} 

@Override 
public void onMessage(Message message) { 

    System.out.println("I'm getting message"); 

} 
` 

말해주십시오 겟. 5 월 내가 config (지금은 기본 netbeans 만든 프로젝트)에 뭔가를 써야합니다.

알렉세이

+0

이것을 알아 냈습니까? 나는 같은 문제에 뛰어 들고있다. 나는 어떤 오류도 내지 않지만 어떤 메시지도받지 못한다. 나는 심지어 모든 연결 정보를 관리 객체 속성에 넣습니다. – Armand

+0

@Armand Hello. 아니요,이 작업은 취소되었습니다. 나는이 일에 나중에 다시 참여할 가능성이있다. – asu

답변

1

나는 해결책이있다. 그것은 최선의 해결책은 아니지만 매우 잘 작동합니다. 우리가 무슨 짓을

는 IBM com.ibm.mq.connector.inbound.ActivationSpecImpl 클래스를 확장 할 수있는 매우 간단한 ActivationSpecWrapper 클래스를 만드는 것입니다. 이 래퍼 클래스에는 public set/get 속성 (asJNDI)이 있습니다. 클래스가 JNDI 컨텍스트를 통해 MDB를 활성화 할 때 할당 할 모든 속성을 포함하는 App 서버에 정의 된 Properties 클래스를 읽어야하는 경우.

우선 ActivationSpecWrapper 클래스를 새로 만듭니다. 원하는 패키지에 넣을 수 있습니다.

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.util.Properties; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.naming.InitialContext; 
import com.ibm.mq.connector.inbound.ActivationSpecImpl; 

public class ActivationSpecWrapper extends ActivationSpecImpl 
{ 

    private static final long serialVersionUID = -529716553593856979L; 

    private static final String sourceClass  = ActivationSpecWrapper.class.getName(); 
    private static final Logger log    = Logger.getLogger(sourceClass); 

    private String    asJNDI   = null; 

    public void setAsJNDI(String asJNDI) 
    { 
     log.config("asJNDI = " + asJNDI); 
     this.asJNDI = asJNDI; 

     try 
     { 
     final InitialContext ctx = new InitialContext(); 
     final Properties properties = (Properties) ctx.lookup(asJNDI); 

     for (final Object key : properties.keySet()) 
     { 
      try 
      { 
       final String value = properties.getProperty((String) key); 
       final Object field = getSetter((String) key); 
       if (field != null) 
       { 
        if (field instanceof Field) 
        { 
        log.fine("Setting " + key + " via Field " + (String) key + " = " + value); 
        ((Field) field).set(this, value); 

        } 
        else 
        { 
        log.fine("Setting " + key + " via Method " + (String) key + " = " + value); 
        ((Method) field).invoke(this, value); 
        } 
        log.config(key + " = " + value); 
       } 
       else 
       { 
        log.warning("Invalid ActivationSpec Field: " + key); 
       } 
      } 
      catch (final NoSuchFieldException e) 
      { 
       log.throwing(sourceClass, "setAsJNDI", e); 
      } 

     } 

     } 
     catch (final Exception e) 
     { 
     log.log(Level.SEVERE, "Error looking up " + asJNDI, e); 
     return; 
     } 

    } 

    public String getAsJNDI() 
    { 
     return asJNDI; 
    } 

    private static Object getField(String fieldName) throws NoSuchFieldException 
    { 
     return ActivationSpecWrapper.class.getField(fieldName); 
    } 

    private static Object getSetter(String fieldName) throws NoSuchFieldException 
    { 
     try 
     { 
     final StringBuilder sb = new StringBuilder(fieldName.length() + 3).append("set").append(fieldName); 
     sb.setCharAt(3, Character.toUpperCase(sb.charAt(3))); 

     return ActivationSpecWrapper.class.getMethod(sb.toString(), String.class); 
     } 
     catch (final NoSuchMethodException e) 
     { 
     return getField(fieldName); 
     } 
    } 
} 

방금 ​​ 파일 wmq.jmsra.rar 내부 META-INF/ra.xml 파일을 수정하는 데 필요한 클래스를 구현합니다. ActivationSpecImpl 클래스의 한 번 발생을 클래스로 변경하십시오. 새 수신 연결 팩토리의 ActivationSpecWrapper 클래스가 사용됩니다. 이제 래퍼 클래스는 사용할 속성에 대해 앱 서버를 살펴볼 수 있습니다. 다음과 같이

내가 이렇게 : 변경 후

<activationspec> 
    <activationspec-class> 
     com.ibm.mq.connector.inbound.ActivationSpecImpl 
    </activationspec-class> 
    <required-config-property> 
     <config-property-name>destination</config-property-name> 
    </required-config-property> 
    <required-config-property> 
     <config-property-name>destinationType</config-property-name> 
    </required-config-property> 
</activationspec> 

META-INF/RA :

: jar -xvf wmq.jmsra.rar META-INF/ra.xml 
: perl -pi -e 's/com\.ibm\.mq\.connector\.inbound\.ActivationSpecImpl/your.new.package.ActivatonSpecWrapper/g' META-INF/ra.xml 
: jar -uvf wmq.jmsra.rar META-INF/ra.xml 

META-INF/ra.xml을 수정하기 전에처럼 보인다 .xml은 다음과 같아야합니다.

<activationspec> 
    <activationspec-class> 
     your.new.package.ActivatonSpecWrapper 
    </activationspec-class> 
    <required-config-property> 
     <config-property-name>destination</config-property-name> 
    </required-config-property> 
    <required-config-property> 
     <config-property-name>destinationType</config-property-name> 
    </required-config-property> 
</activationspec> 

이제 RAR 파일에 새 패키지를 추가해야합니다. 표준 디렉토리 구조에 있어야합니다.

: jar -uvf wmq.jmsra.rar your/new/package/ActivationSpecWrapper.class 

문제는 활성화 사양 대신 관리 개체로 호스트/포트/큐 관리자/채널 (등)을 배치하는 IBM 유래이있다. MDB 큐의 연결 팩토리이므로 관리 객체에 속합니다. IBM은 두 가지 특성 만 허용합니다. 자원 어댑터를 필요로 MDB 클래스

는 글래스 피쉬를 사용하는 경우 또한, 오라클은 정말 것이지 일까지, 글래스 피쉬 @MessageDriven 주석이 JMS의 앱 컨테이너의 기본 자원 어댑터 (OpenMQ)을 가정하기 때문이다. 이 작동하지 않습니다 벤더 고유 ActivationSpecImpl을 의미하며, 따라서 호스트/포트 및 기타 활성 구성 속성에 대한 IMB의 사용자 정의 매개 변수는 자원 어댑터가 글래스 피쉬 - EJB-jar.xml의를 통해 스위치입니다 때까지 주석을 통해 지원되지 않습니다.

JBoss는 자원 어댑터를 변경하는 @ResourceAdapter 주석을 허용하지만, 글래스 피시 만 글래스 피쉬 - EJB-jar.xml의 파일을 통해이 작업을 할 수 있습니다. 그리고 이것을 사용하면 MDB에 3 개의 활성화 구성 등록 정보 (대상 유형) 만 주석 처리하면됩니다. 당신이 JNDI에 게시 할 다른 모든 것들을 배치 할 것입니다.

글래스 피쉬 - EJB-jar.xml의은 다음과 같아야합니다

<?xml version="1.0" encoding="UTF-8"?> 
<glassfish-ejb-jar> 

    <enterprise-beans > 
     <unique-id>1</unique-id> 
     <ejb> 
      <ejb-name>MyMDB</ejb-name> 
      <mdb-resource-adapter> 
       <resource-adapter-mid>wmq.jmsra</resource-adapter-mid> 
       <activation-config> 
        <activation-config-property> 
         <activation-config-property-name>asJNDI</activation-config-property-name> 
         <activation-config-property-value>mq/InboundMessages</activation-config-property-value> 
        </activation-config-property> 
       </activation-config> 
      </mdb-resource-adapter> 
     </ejb> 
    </enterprise-beans> 
</glassfish-ejb-jar> 

MDB를 @MessageDriven 주석은 다음과 같이 보일 것이다 :

@MessageDriven(activationConfig = 
    { 
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), 
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/InboundMessage_queue"), 
    @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true") }) 
public class MyMDB implement MessageListener 
{ 
    public void onMessage(Message message) 
    { 
     // message handler code goes here... 
    } 
} 

마지막을 이 작업을 수행하는 단계는 mq/InboundMessages 속성을 JDNI에 추가하여 정의하는 것입니다. MQ 리스너 자원에 대한 팩토리 특성. 이것은이 domain.xml의 파일에 정의 된 방법입니다

<custom-resource res-type="java.util.Properties" jndi-name="mq/InboundMessages" factory-class="org.glassfish.resources.custom.factory.PropertiesFactory"> 
    <property name="hostName" value="mqserver"></property> 
    <property name="port" value="1422"></property> 
    <property name="queueManager" value="MQMNGR"></property> 
    <property name="channel" value="MQMNGR.SM.S1"></property> 
    <property name="transportType" value="CLIENT"></property> 
</custom-resource> 

도움이 되었기를 바랍니다. 이것은 가장 쉬운 솔루션은 아니지만 간단하다. 일단 설치가되면, 이식성이 뛰어나며 앱 서버 관리자는 개발자가 아닌 MQ에 연결 세부 정보를 관리 할 수있다.

+0

안녕하세요! Armand 감사합니다. 1 년 후에 나는이 일로 돌아 간다. 당신의 대답은 매우 도움이되었습니다. glassfish-ejb-jar.xml 파일을 만들고 MQQueueManger 연결 속성을 사용하여 wmq.jmsra asu

+0

IBM은 JMS ResourceAdaptor에서 트랜잭션을 지원하지 않습니다. XA-Transactions에 대한 지원을 구현하는 것은 매우 쉽습니다. *** com.ibm.mqetclient를 추가하십시오.jar *** 파일을 RAR 파일에 추가하면 XA 트랜잭션이 MDB에서 지원됩니다. 또한 MQ7에서는이 모든 작업을 수행하지만 MQ6에서도 작동합니다. – Armand

+0

이와 같은 자세한 답변을 주셔서 대단히 감사합니다. – asu