在 JBoss 5.1.0 GA 中使用来自 MDB 的身份验证连接到 weblogic 10.3.6 JMS 队列时出现问题
Problems connecting to weblogic 10.3.6 JMS Queue with authentication from MDB in JBoss 5.1.0 GA
我正在使用 sun-jms-adapter.rar。在开始使用身份验证之前,我的所有配置都工作正常。我还尝试从独立应用程序和无状态 bean(用于将消息发送到队列)访问队列,一切正常。
我的实际配置是:
weblogic-ds.xml
<connection-factories>
<!-- SUN JMS JCA Resource adapter, use this to get transacted JMS in beans -->
<no-tx-connection-factory>
<jndi-name>CFX/ExternalConnectionFactory</jndi-name>
<xa-transaction />
<rar-name>sun-jms-adapter.rar</rar-name>
<connection-definition>javax.jms.QueueConnectionFactory</connection-definition>
<config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
<config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultJMSProvider</config-property>
<config-property name="Destination" type="java.lang.String">javax.jms.Destination</config-property>
<max-pool-size>20</max-pool-size>
<depends>jboss.messaging:service=ServerPeer</depends>
</no-tx-connection-factory>
</connection-factories>
ejb-jar.xml配置:
<enterprise-beans>
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<ejb-class>com.tests.mdb.QueueReceiverMDB</ejb-class>
<transaction-type>Bean</transaction-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.queue.in}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>ConnectionURL</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.url}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>UserName</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.username}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>Password</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.password}</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
最后是我的 jboss.xml:
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<destination-jndi-name>java:/CFX/ExternalConnectionFactory</destination-jndi-name>
<local-jndi-name>local/QueueReceiverMDB</local-jndi-name>
<resource-adapter-name>sun-jms-adapter.rar</resource-adapter-name>
<configuration-name>JMSJCA Message Driven Bean</configuration-name>
</message-driven>
我总是收到这个错误:
16:25:07,126 WARNING [Activation] JMSJCA-E016: [sync-QueueReceiver(jms/TestJMSQueueIn) @ [t3://localhost:7001]]: message delivery initiation failed (attempt #1); will retry in 1 seconds. The error was: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45)
at weblogic.jms.client.JMSSession.consumerCreate(JMSSession.java:2982)
at weblogic.jms.client.JMSSession.setupConsumer(JMSSession.java:2749)
at weblogic.jms.client.JMSSession.createConsumer(JMSSession.java:2691)
at weblogic.jms.client.JMSSession.createReceiver(JMSSession.java:2596)
at weblogic.jms.client.WLSessionImpl.createReceiver(WLSessionImpl.java:991)
at com.stc.jmsjca.core.RAJMSObjectFactory.createMessageConsumer(RAJMSObjectFactory.java:620)
at com.stc.jmsjca.core.SyncDelivery$SyncWorker.init(SyncDelivery.java:502)
at com.stc.jmsjca.core.SyncDelivery.start(SyncDelivery.java:202)
at com.stc.jmsjca.core.Activation.asyncStart(Activation.java:557)
at com.stc.jmsjca.core.Activation.access[=14=]0(Activation.java:82)
at com.stc.jmsjca.core.Activation.run(Activation.java:351)
at java.lang.Thread.run(Thread.java:745)
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45)
at weblogic.jms.frontend.FEConsumer.(FEConsumer.java:296)
at weblogic.jms.frontend.FESession.run(FESession.java:1076)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.jms.frontend.FESession.consumerCreate(FESession.java:1072)
at weblogic.jms.frontend.FESession.invoke(FESession.java:3027)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961)
at weblogic.messaging.dispatcher.DispatcherServerRef.invoke(DispatcherServerRef.java:276)
at weblogic.messaging.dispatcher.DispatcherServerRef.handleRequest(DispatcherServerRef.java:141)
at weblogic.messaging.dispatcher.DispatcherServerRef.access[=14=]0(DispatcherServerRef.java:34)
at weblogic.messaging.dispatcher.DispatcherServerRef.run(DispatcherServerRef.java:111)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.Request.handleThrowable(Request.java:87)
at weblogic.jms.dispatcher.Request.getResult(Request.java:52)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:1124)
at weblogic.messaging.dispatcher.DispatcherImpl.syncRequest(DispatcherImpl.java:185)
at weblogic.messaging.dispatcher.DispatcherImpl.dispatchSync(DispatcherImpl.java:220)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:43)
... 13 more
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.common.JMSSecurityHelper.checkPermission(JMSSecurityHelper.java:162)
at weblogic.jms.backend.BEDestinationSecurityImpl.checkReceivePermission(BEDestinationSecurityImpl.java:87)
at weblogic.jms.backend.BEConsumerImpl.init(BEConsumerImpl.java:312)
at weblogic.jms.backend.BEConsumerImpl.(BEConsumerImpl.java:268)
at weblogic.jms.backend.BEQueueImpl.createConsumer(BEQueueImpl.java:188)
at weblogic.jms.backend.BESessionImpl.createBEConsumer(BESessionImpl.java:469)
at weblogic.jms.backend.BESessionImpl.createConsumer(BESessionImpl.java:479)
at weblogic.jms.backend.BESessionImpl.invoke(BESessionImpl.java:297)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961)
... 16 more
欢迎任何建议...
我找到了解决我的问题的方法,可能不是最好的,但很有效。
在花了很多时间尝试让它工作之后,我从 here 中检查了资源适配器 (sun-jms-adapter.rar) 的源代码,并发现了一个可能的错误。他们不会在创建会话后将凭据放入 initialContext 和关闭上下文。因此,我通过将 "Context.SECURITY_PRINCIPAL" 和 "Context.SECURITY_CREDENTIALS" 添加到上下文来修改此步骤,并将其保持打开状态。这确实有效。所有这些都在 RAWLObjectFactory class.
中的 getJndiObject 方法中
如果有人找到另一种方法,最好的方法,请分享...因为他们在创建队列连接时放置凭据,所以可能是 weblogic 源中的错误。
我留下修改后的代码:
private Object getJndiObject(UrlParser url, String name, String username, String password) throws JMSException {
if (sLog.isDebugEnabled()) {
sLog.debug("Looking up JNDI object " + name);
}
if (name == null || name.length() == 0) {
throw Exc.jmsExc(LOCALE.x("E401: The JNDI name is null"));
}
InitialContext ctx = null;
try {
if (mSpecialISORBMethod != null) {
// Works on IS only
if (mSpecialISORBMethodIsOn != null) {
Boolean isEnabled = (Boolean) mSpecialISORBMethodIsOn.invoke(null, new Object[0]);
if (!isEnabled.booleanValue()) {
throw Exc.rsrcExc(LOCALE.x("E823: CORBA-SE needs to be enabled on"
+ " this server. Please change the value of the <se-orb enabled=\"false\"/>"
+ " to <se-orb enabled=\"true\"/> in the configuration file of "
+ " the Integration Server (logicalhost/is/domains/<domain-name>"
+ "/config/domain.xml) and restart the server."));
}
}
final Properties prop = (Properties) mSpecialISORBMethod.invoke(null, new Object[0]);
prop.put(Context.URL_PKG_PREFIXES, JNDI_WEBLOGIC_PROTOCOL_PACKAGES);
ctx = new InitialContext(prop);
return ctx.lookup("corbaname:iiop:1.2@" + url.getHost() + ":" + url.getPort()
+ '#' + name);
} else {
// Will be executed on other application servers than the IS
//add username/password if not null to context
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, "t3://" + url.getHost() + ":" + url.getPort());
if (username != null) {
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
}
ctx = new InitialContext(env);
return ctx.lookup(name);
}
} catch (Exception e) {
throw Exc.jmsExc(LOCALE.x("E821: Could not find JNDI object by name [{0}]: {1}", name, e), e);
}
//leave context open
/*finally {
safeClose(ctx);
}*/
}
我正在使用 sun-jms-adapter.rar。在开始使用身份验证之前,我的所有配置都工作正常。我还尝试从独立应用程序和无状态 bean(用于将消息发送到队列)访问队列,一切正常。
我的实际配置是:
weblogic-ds.xml
<connection-factories>
<!-- SUN JMS JCA Resource adapter, use this to get transacted JMS in beans -->
<no-tx-connection-factory>
<jndi-name>CFX/ExternalConnectionFactory</jndi-name>
<xa-transaction />
<rar-name>sun-jms-adapter.rar</rar-name>
<connection-definition>javax.jms.QueueConnectionFactory</connection-definition>
<config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
<config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultJMSProvider</config-property>
<config-property name="Destination" type="java.lang.String">javax.jms.Destination</config-property>
<max-pool-size>20</max-pool-size>
<depends>jboss.messaging:service=ServerPeer</depends>
</no-tx-connection-factory>
</connection-factories>
ejb-jar.xml配置:
<enterprise-beans>
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<ejb-class>com.tests.mdb.QueueReceiverMDB</ejb-class>
<transaction-type>Bean</transaction-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.queue.in}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>ConnectionURL</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.url}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>UserName</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.username}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>Password</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.password}</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
最后是我的 jboss.xml:
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<destination-jndi-name>java:/CFX/ExternalConnectionFactory</destination-jndi-name>
<local-jndi-name>local/QueueReceiverMDB</local-jndi-name>
<resource-adapter-name>sun-jms-adapter.rar</resource-adapter-name>
<configuration-name>JMSJCA Message Driven Bean</configuration-name>
</message-driven>
我总是收到这个错误:
16:25:07,126 WARNING [Activation] JMSJCA-E016: [sync-QueueReceiver(jms/TestJMSQueueIn) @ [t3://localhost:7001]]: message delivery initiation failed (attempt #1); will retry in 1 seconds. The error was: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110) at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45) at weblogic.jms.client.JMSSession.consumerCreate(JMSSession.java:2982) at weblogic.jms.client.JMSSession.setupConsumer(JMSSession.java:2749) at weblogic.jms.client.JMSSession.createConsumer(JMSSession.java:2691) at weblogic.jms.client.JMSSession.createReceiver(JMSSession.java:2596) at weblogic.jms.client.WLSessionImpl.createReceiver(WLSessionImpl.java:991) at com.stc.jmsjca.core.RAJMSObjectFactory.createMessageConsumer(RAJMSObjectFactory.java:620) at com.stc.jmsjca.core.SyncDelivery$SyncWorker.init(SyncDelivery.java:502) at com.stc.jmsjca.core.SyncDelivery.start(SyncDelivery.java:202) at com.stc.jmsjca.core.Activation.asyncStart(Activation.java:557) at com.stc.jmsjca.core.Activation.access[=14=]0(Activation.java:82) at com.stc.jmsjca.core.Activation.run(Activation.java:351) at java.lang.Thread.run(Thread.java:745) Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110) at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45) at weblogic.jms.frontend.FEConsumer.(FEConsumer.java:296) at weblogic.jms.frontend.FESession.run(FESession.java:1076) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146) at weblogic.jms.frontend.FESession.consumerCreate(FESession.java:1072) at weblogic.jms.frontend.FESession.invoke(FESession.java:3027) at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961) at weblogic.messaging.dispatcher.DispatcherServerRef.invoke(DispatcherServerRef.java:276) at weblogic.messaging.dispatcher.DispatcherServerRef.handleRequest(DispatcherServerRef.java:141) at weblogic.messaging.dispatcher.DispatcherServerRef.access[=14=]0(DispatcherServerRef.java:34) at weblogic.messaging.dispatcher.DispatcherServerRef.run(DispatcherServerRef.java:111) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256) at weblogic.work.ExecuteThread.run(ExecuteThread.java:221) Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive at weblogic.jms.dispatcher.Request.handleThrowable(Request.java:87) at weblogic.jms.dispatcher.Request.getResult(Request.java:52) at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:1124) at weblogic.messaging.dispatcher.DispatcherImpl.syncRequest(DispatcherImpl.java:185) at weblogic.messaging.dispatcher.DispatcherImpl.dispatchSync(DispatcherImpl.java:220) at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:43) ... 13 more Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive at weblogic.jms.common.JMSSecurityHelper.checkPermission(JMSSecurityHelper.java:162) at weblogic.jms.backend.BEDestinationSecurityImpl.checkReceivePermission(BEDestinationSecurityImpl.java:87) at weblogic.jms.backend.BEConsumerImpl.init(BEConsumerImpl.java:312) at weblogic.jms.backend.BEConsumerImpl.(BEConsumerImpl.java:268) at weblogic.jms.backend.BEQueueImpl.createConsumer(BEQueueImpl.java:188) at weblogic.jms.backend.BESessionImpl.createBEConsumer(BESessionImpl.java:469) at weblogic.jms.backend.BESessionImpl.createConsumer(BESessionImpl.java:479) at weblogic.jms.backend.BESessionImpl.invoke(BESessionImpl.java:297) at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961) ... 16 more
欢迎任何建议...
我找到了解决我的问题的方法,可能不是最好的,但很有效。
在花了很多时间尝试让它工作之后,我从 here 中检查了资源适配器 (sun-jms-adapter.rar) 的源代码,并发现了一个可能的错误。他们不会在创建会话后将凭据放入 initialContext 和关闭上下文。因此,我通过将 "Context.SECURITY_PRINCIPAL" 和 "Context.SECURITY_CREDENTIALS" 添加到上下文来修改此步骤,并将其保持打开状态。这确实有效。所有这些都在 RAWLObjectFactory class.
中的 getJndiObject 方法中如果有人找到另一种方法,最好的方法,请分享...因为他们在创建队列连接时放置凭据,所以可能是 weblogic 源中的错误。
我留下修改后的代码:
private Object getJndiObject(UrlParser url, String name, String username, String password) throws JMSException {
if (sLog.isDebugEnabled()) {
sLog.debug("Looking up JNDI object " + name);
}
if (name == null || name.length() == 0) {
throw Exc.jmsExc(LOCALE.x("E401: The JNDI name is null"));
}
InitialContext ctx = null;
try {
if (mSpecialISORBMethod != null) {
// Works on IS only
if (mSpecialISORBMethodIsOn != null) {
Boolean isEnabled = (Boolean) mSpecialISORBMethodIsOn.invoke(null, new Object[0]);
if (!isEnabled.booleanValue()) {
throw Exc.rsrcExc(LOCALE.x("E823: CORBA-SE needs to be enabled on"
+ " this server. Please change the value of the <se-orb enabled=\"false\"/>"
+ " to <se-orb enabled=\"true\"/> in the configuration file of "
+ " the Integration Server (logicalhost/is/domains/<domain-name>"
+ "/config/domain.xml) and restart the server."));
}
}
final Properties prop = (Properties) mSpecialISORBMethod.invoke(null, new Object[0]);
prop.put(Context.URL_PKG_PREFIXES, JNDI_WEBLOGIC_PROTOCOL_PACKAGES);
ctx = new InitialContext(prop);
return ctx.lookup("corbaname:iiop:1.2@" + url.getHost() + ":" + url.getPort()
+ '#' + name);
} else {
// Will be executed on other application servers than the IS
//add username/password if not null to context
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, "t3://" + url.getHost() + ":" + url.getPort());
if (username != null) {
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
}
ctx = new InitialContext(env);
return ctx.lookup(name);
}
} catch (Exception e) {
throw Exc.jmsExc(LOCALE.x("E821: Could not find JNDI object by name [{0}]: {1}", name, e), e);
}
//leave context open
/*finally {
safeClose(ctx);
}*/
}