I'm testing out TomEE+ because it wraps a lot of features I need in a new system. Apache ActiveMQ being one of them. But I have some difficulties getting the JMS to work, and my efforts to find a solution havent yielded any results. I even tried to google for an answer!
Even when I try the "out-of-the-box" example:
import javax.annotation.Resource;
import javax.servlet.http.HttpServlet;
import javax.jms.Topic;
import javax.jms.Queue;
import javax.jms.ConnectionFactory;
public class MyServet extends HttpServlet {
#Resource(name = "foo")
private Topic fooTopic;
#Resource(name = "bar")
private Queue barQueue;
#Resource
private ConnectionFactory connectionFactory;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//...
Connection connection = connectionFactory.createConnection();
connection.start();
// Create a Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create a MessageProducer from the Session to the Topic or Queue
MessageProducer producer = session.createProducer(fooTopic);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// Create a message
TextMessage message = session.createTextMessage("Hello World!");
// Tell the producer to send the message
producer.send(message);
//...
}
}
I get the same problems, my ConnectionFactory is null. When I debug I can see that this is the case with all my #Resource annotated members. I would think that my members would be instanciated through injection when correctly annotated?
I tried to add this to my tomee.xml, with no result:
<Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
BrokerXmlConfig = broker:(tcp://localhost:61616)
ServerUrl = tcp://localhost:61616
</Resource>
<Resource id="MyJmsConnectionFactory" type="javax.jms.ConnectionFactory">
ResourceAdapter = MyJmsResourceAdapter
</Resource>
<Container id="MyJmsMdbContainer" ctype="MESSAGE">
ResourceAdapter = MyJmsResourceAdapter
</Container>
<Resource id="bar" type="javax.jms.Queue"/>
<Resource id="foo" type="javax.jms.Topic"/>
Still I get a NullPointerException when I run the example. Any suggestions as to where I might be missing something. Besides the addition to the tomee.xml I am running the 1.5.1 version of TomEE+ with nothing changed.
Thanks in advance
Change the connection factory resource code to following. It should work
#Resource(name = "MyJMSConnectionFactory", type = ConnectionFactory.class)
private ConnectionFactory connectionFactory;
Related
I tried to testing my Dao class but it return this error for the class DbConnection:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.initial
at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:691)
at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at java.naming/javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:342)
at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
at model.DbConnection.(DbConnection.java:16)
at model.DbConnection.getInstance(DbConnection.java:30)
at model.ProfileManager.ReturnPatientByKey(ProfileManager.java:27)
at model.ProfileManagerTest.testReturnPatientByKey(ProfileManagerTest.java:32)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
....
my DbConnection class:
package model;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DbConnection {
private DbConnection() {
Context ctx;
try {
ctx = new InitialContext();
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static DbConnection getInstance () {
if(db==null) {
return new DbConnection();
}
else {
return db;
}
}
private static DataSource ds;
private static DbConnection db;
}
Database connection works in the web application, only the testing return this error.
I don't think the problem si my class ProfileManager because it is only a testing example:
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import model.Bean.PatientBean;
class ProfileManagerTest{
private ProfileManager pm;
String fiscal_code;
String user_password;
PatientBean patient;
#BeforeEach
void setUp() throws Exception {
this.pm = new ProfileManager();
fiscal_code = "aaa";
user_password = "bbb";
patient = mock(PatientBean.class);
}
#AfterEach
void tearDown() throws Exception {
}
#Test
void testReturnPatientByKey() {
patient = (PatientBean) pm.ReturnPatientByKey(fiscal_code, user_password);
assertTrue(true);
}
}
Database connection works in the web application, only the testing return this error.
That's most likely because you have the datasource declared in the server configuration and the server is providing your web app with one, but you don't have the same done in your test.
Do a search in your server files an you will probably discover something like this, or similar, depending on what server you use:
<Resource name="jdbc/CheckUpDb"
driverClassName="..."
type="..."
url="..."
username="..."
password="..."
/>
This is a way to configure a datasource using JNDI. When your web application runs, the server will provide you with this resource by name. This is what ctx.lookup("java:comp/env/jdbc/CheckUpDb"); does. It asks the server to give it that resource.
But when you run your unit tests, you run outside the server environment. That means that any resource you defined in the server (using context.xml for example) doesn't exist when you run your tests. In your tests you have to provide a datasource and make it available to your JNDI context so that this line of code then works:
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
The following post should give you the necessary details to set up your JNDI data source for your test: Setting up JNDI Datasource in jUnit
You will see that the examples there make use of a library called Simple-Jndi that they use to provide a JNDI context and configure it to include the datasource that the tests then try to retrieve by name. You can use any JNDI provider, but you must set up the datasource for your test yourself (inside #BeforeEach or #BeforeAll) because when running unit tests, you don't have the tomcat server doing this for you.
I already found out how to create an Oracle database with AQ (Streams?) packages. I also created some queue's in Oracle (by hand). (Using PL/SQL and SQL).
However, I'm having a hard time setting up a proper connection from Spring.
The following works (using oracle.AQ java package):
private final String aqUrl = "jdbc:oracle:thin:#localhost:1521:orcl";
private final String aqUser = "queue_mut";
private final String aqPassword = "******";
private final String aqSchema = "queue_mut";
private final String aqTable = "aq_table1";
private final String aqQueue = "aq_queue1";
#Test
public void testManualAQ() throws ClassNotFoundException, SQLException, AQException {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = DriverManager.getConnection(aqUrl, aqUser, aqPassword);
connection.setAutoCommit(false);
Class.forName("oracle.AQ.AQOracleDriver");
AQSession aqSession = AQDriverManager.createAQSession(connection);
AQQueueTable q_table = aqSession.createQueueTable(aqSchema, aqTable, new AQQueueTableProperty("RAW"));
aqSession.createQueue(q_table, aqQueue, new AQQueueProperty());
}
(based on https://docs.oracle.com/cd/B10501_01/appdev.920/a96587/apexampl.htm)
This shows me that I can connect to Oracle and reach AQ functionality.
Now, I'm trying to create Java Configured beans in order to use the JmsTemplate.
#Resource
private JmsTemplate jmsTemplate;
#Test
public void testJmsTemplate() {
String xmlval = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<product id=\"10\">\n" +
" <description>Foo</description>\n" +
" <price>2.05</price>\n" +
"</product>";
jmsTemplate.convertAndSend(aqSchema + ".jms_ws_incoming_queue", xmlval);
}
(yes, the queue already exists ;-))
With the following configuration class:
import oracle.jms.AQjmsFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.sql.DataSource;
#Configuration
public class OracleAQConfiguration {
#Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}
#Bean
public ConnectionFactory connectionFactory(DataSource dataSource) throws JMSException {
return AQjmsFactory.getQueueConnectionFactory(dataSource);
}
#Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setSessionTransacted(true);
jmsTemplate.setConnectionFactory(connectionFactory);
return jmsTemplate;
}
}
And with properties yml:
spring:
datasource:
url: jdbc:oracle:thin:#localhost:1521:orcl
username: queue_mut
password: ******
driverClassName: oracle.jdbc.driver.OracleDriver
But with this I get errors which I cannot grasp:
2017-04-19 12:11:17,151 INFO my.project.QueueTest: Started QueueTest in 5.305 seconds (JVM running for 6.588)
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is oracle.jms.AQjmsException: Error creating the db_connection; nested exception is java.lang.ClassCastException: com.sun.proxy.$Proxy102 cannot be cast to oracle.jdbc.internal.OracleConnection
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:658)
at my.project.QueueTest.testJmsTemplate(QueueTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: oracle.jms.AQjmsException: Error creating the db_connection
at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:625)
at oracle.jms.AQjmsDBConnMgr.<init>(AQjmsDBConnMgr.java:399)
at oracle.jms.AQjmsConnection.<init>(AQjmsConnection.java:249)
at oracle.jms.AQjmsConnectionFactory.createConnection(AQjmsConnectionFactory.java:513)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
... 36 more
Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy102 cannot be cast to oracle.jdbc.internal.OracleConnection
at oracle.jms.AQjmsGeneralDBConnection.getProviderKey(AQjmsGeneralDBConnection.java:98)
at oracle.jms.AQjmsGeneralDBConnection.<init>(AQjmsGeneralDBConnection.java:67)
at oracle.jms.AQjmsDBConnMgr.getConnection(AQjmsDBConnMgr.java:566)
... 41 more
I believe that the Cast exception occurs because it is a ProxyConnection[PooledConnection[oracle.jdbc.driver.T4CConnection#40016ce1]]. But I don't know how to fix this.
Change the jdbc library, in my case this fixed it(if don't, try with some other versions):
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2.0</version>
</dependency>
We experienced the same exception when tried to access Oracle AQ from Spring boot. Research indicated that this exception is thrown as the Database connection pool libraries doesn't allow the access to the underlying connection required by the oracle AQ Library.(Both dbcp and tomcat connection pool libraries threw exceptions , not same but similar)
This exception was gone when we removed the Database connection pool libraries from dependencies which lead to an undesirable state of having no Database connection pooling for the entire application .
We noticed that the if we use the following method the exception is not thrown
AQjmsFactory.getQueueConnectionFactory(url, info);
Perhaps connection pooling is missing with solution also, but that is limited to the component which reads from AQ . Other components in the app will have the benefits of the connection pooling
Here is the java config for the Bean definition:
#Bean
public QueueConnectionFactory connectionFactory() throws Exception {
OracleServiceInfo serviceInfo = (OracleServiceInfo) this.cloud().getServiceInfo(NAME_PRIMARY_DS);
Properties info = new Properties();
String url = serviceInfo.getJdbcUrl();
info.put("driver-name", "oracle.jdbc.OracleDriver");
info.put("user", serviceInfo.getUserName());
info.put("password", serviceInfo.getPassword());
return oracle.jms.AQjmsFactory.getQueueConnectionFactory(url, info);
}
#Bean
public JmsTemplate jmsTemplate() throws Exception {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory());
return jmsTemplate;
}
I am not sure yet if this a good solution. But this is definitely one way to get rid of the exception discussed in the question.
Hi it also took me quite some time to make the connection work, but finally it did and this is how:
First make sure the payload of your Oracle AQ Queue table is not set to RAW but preferably to Text: SYS.AQ$_JMS_TEXT_MESSAGE
Next use a OracleAQConfiguration similar as hereunder:
import oracle.jdbc.pool.OracleDataSource;
import oracle.jms.AQjmsFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.jms.JMSException;
import javax.jms.QueueConnectionFactory;
import javax.sql.DataSource;
import java.sql.SQLException;
#Configuration
public class OracleAQConfiguration {
// Values are retrieved from custom added props in Spring application.properties
#Value("${myapplication.datasource.user}")
private String user;
#Value("${myapplication.datasource.password}")
private String password;
#Value("${myapplication.datasource.connectionstring}")
private String connectionstring;
#Bean
/**
* Spring bean with the configuration details of where the Oracle database is containing the QUEUES
*/
public DataSource dataSource() throws SQLException {
OracleDataSource ds = new OracleDataSource();
ds.setUser(user);
ds.setPassword(password);
ds.setURL(connectionstring);
ds.setImplicitCachingEnabled(true);
ds.setFastConnectionFailoverEnabled(true);
return ds;
}
#Bean
/**
* The KEY component effectively connecting to the Oracle AQ system using the datasource input
*/
public QueueConnectionFactory connectionFactory(DataSource dataSource) throws JMSException {
return AQjmsFactory.getQueueConnectionFactory(dataSource);
}
}
Next use a JMSConfiguration similar as hereunder.
Here I read and write to the same queue which is unlikely in a real application integration scenario. But OK for testing
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import javax.jms.ConnectionFactory;
import javax.sql.DataSource;
#Configuration
public class JMSConfiguration {
private static final String QUEUENAME_WRITE = "MYQUEUE";
private static final String QUEUENAME_READ = "MYQUEUE";
#Autowired
private JMSReceiver jmsReceiver;
#Bean
/**
* Spring bean to WRITE/SEND/ENQUEUE messages on a queue with a certain name
*/
public JmsTemplate jmsTemplate(ConnectionFactory conFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setDefaultDestinationName(QUEUENAME_WRITE);
jmsTemplate.setSessionTransacted(true);
jmsTemplate.setConnectionFactory(conFactory);
return jmsTemplate;
}
/**
* Spring bean to READ/RECEIVE/DEQUEUE messages of a queue with a certain name
* All of this happens under a code managed transaction
* to commit the change on Oracle (remove of the message from the queue table)
* Reference the application custom code handling the message here
*/
#Bean
public DefaultMessageListenerContainer messageListenerContainer(ConnectionFactory conFactory, DataSource dataSource) {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setDestinationName(QUEUENAME_READ);
dmlc.setSessionTransacted(true);
dmlc.setConnectionFactory(conFactory);
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
dmlc.setTransactionManager(manager);
// Add here our self-written JMS Receiver
dmlc.setMessageListener(jmsReceiver);
return dmlc;
}
}
Finally for handling incoming JMS messages use something like:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
#Component
public class JMSReceiver implements SessionAwareMessageListener {
private static final Logger logger = LoggerFactory.getLogger(JMSReceiver.class);
#Override
public void onMessage(Message message, Session session) throws JMSException {
// We know/assume the Queue Payload type was set to 'TextMessage'
TextMessage txtMessage = (TextMessage) message;
logger.info("JMS Text Message received: " + txtMessage.getText());
// ... further implementation
}
}
the problem is that the AQ code expected an OracleConnection but when pooled the connection wrapped and hence it fails
I am using jboss 5.1.0 GA. I am trying to create a helloworldjMS.java. The code is as follows,
import java.util.Hashtable;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
public class HelloWorldJMS {
public static void main(String[] args) {
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
env.put(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
// Create the initial context
Context ctx = new InitialContext(env);
// Lookup the JMS connection factory from the JBoss 5.1 object store
ConnectionFactory connectionFactory = (ConnectionFactory) ctx
.lookup("ConnectionFactory");
// Lookup a queue from the JBoss 5.1 object store
Queue queue = (javax.jms.Queue) ctx.lookup("/queue/DLQ");
// Create a connection to the JBoss 5.1 Message Service
Connection connection = connectionFactory.createConnection();
// Create a session within the connection
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
// Create a message producer to put messages on the queue
MessageProducer messageProducer = session.createProducer(queue);
// Create and send a message to the queue
TextMessage textMessage = session.createTextMessage();
textMessage.setText("Hello World");
System.out.println("Sending Message: " + textMessage.getText());
messageProducer.send(textMessage);
// Create a message consumer
MessageConsumer messageConsumer = session.createConsumer(queue);
// Start the Connection created
connection.start();
// Receive a message from the queue.
Message msg = messageConsumer.receive();
// Retrieve the contents of the message.
if (msg instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) msg;
System.out.println("Read Message: " + txtMsg.getText());
}
// Close the session and connection resources.
session.close();
connection.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I am getting the following error,
org.jboss.jms.exception.MessagingNetworkFailureException
at org.jboss.jms.client.delegate.DelegateSupport.handleThrowable(DelegateSupport.java:245)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.org$jboss$jms$client$delegate$ClientConnectionFactoryDelegate$createConnectionDelegate$aop(ClientConnectionFactoryDelegate.java:187)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.invokeNext(ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.java)
at org.jboss.jms.client.container.StateCreationAspect.handleCreateConnectionDelegate(StateCreationAspect.java:83)
at org.jboss.aop.advice.org.jboss.jms.client.container.StateCreationAspect_z_handleCreateConnectionDelegate_328011903.invoke(StateCreationAspect_z_handleCreateConnectionDelegate_328011903.java)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.invokeNext(ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.java)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.createConnectionDelegate(ClientConnectionFactoryDelegate.java)
at org.jboss.jms.client.JBossConnectionFactory.createConnectionInternal(JBossConnectionFactory.java:205)
at org.jboss.jms.client.JBossConnectionFactory.createConnection(JBossConnectionFactory.java:87)
at org.jboss.jms.client.JBossConnectionFactory.createConnection(JBossConnectionFactory.java:82)
at HelloWorldJMS.main(HelloWorldJMS.java:67)
Caused by: org.jboss.remoting.ConnectionFailedException: Timed out trying to create control socket
at org.jboss.remoting.transport.bisocket.BisocketClientInvoker.handleConnect(BisocketClientInvoker.java:276)
at org.jboss.remoting.MicroRemoteClientInvoker.connect(MicroRemoteClientInvoker.java:309)
at org.jboss.remoting.Client.connect(Client.java:1612)
at org.jboss.remoting.Client.connect(Client.java:515)
at org.jboss.remoting.callback.ServerInvokerCallbackHandler.connect(ServerInvokerCallbackHandler.java:168)
at org.jboss.remoting.ServerInvoker.getCallbackHandler(ServerInvoker.java:2064)
at org.jboss.remoting.ServerInvoker.handleInternalInvocation(ServerInvoker.java:1646)
at org.jboss.remoting.transport.bisocket.BisocketServerInvoker.handleInternalInvocation(BisocketServerInvoker.java:863)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:878)
at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:744)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:697)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:551)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:232)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
at org.jboss.remoting.Client.invoke(Client.java:1550)
at org.jboss.remoting.Client.addCallbackListener(Client.java:1619)
at org.jboss.remoting.Client.addListener(Client.java:913)
at org.jboss.jms.client.remoting.JMSRemotingConnection.addInvokerCallbackHandler(JMSRemotingConnection.java:230)
at org.jboss.jms.client.remoting.JMSRemotingConnection.start(JMSRemotingConnection.java:340)
at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.org$jboss$jms$client$delegate$ClientConnectionFactoryDelegate$createConnectionDelegate$aop(ClientConnectionFactoryDelegate.java:154)
... 9 more
I have the following jars,
concurrent.jar,javassist-3.10.0.GA.jar,jboss-aop-client.jar,jboss-common-core-2.2.10.GA.jar,jboss-common.jar, jboss-j2ee.jar , jboss-mdr-2.0.1.GA.jar, jboss-messaging-client.jar, jboss-remoting.jar, jbossmq.jar, jetty-session-redis-2.3.ga-serialjboss.jar, jnpserver.jar.
I know this is very old jboss questions. But I tried various suggestions, could not find any way. So, i am posting the question. So kindly provide some suggestions.
Thanks
Remove jboss-remoting.jar and add jboss-remoting-4.2.2.GA.jar
I am newbie in JMS and this is my first attempt use it. I use glassfish4. I followed this tutorial I set glassfish resources and in EAR application added message driven bean. Plus I opened 7676 port in firewall. After that I created a SE project (different host,i.e. not the server jvm) with one class SeClient and with the following
package seclient;
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnectionFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
public class SeClient {
public static void main(String a[]) throws Exception {
// Commands to create Topic
// asadmin --port 4848 create-jms-resource --restype javax.jms.Topic TestTopic
// asadmin --port 4848 create-jms-resource --restype javax.jms.TopicConnectionFactory TestTopicConnectionFactory
String msg = "Hello from remote JMS Client";
SeClient test = new SeClient();
System.out.println("==============================");
System.out.println("Publishig message to Topic");
System.out.println("==============================");
System.out.println();
test.sendMessage2Topic(msg);
System.out.println();
System.out.println("==============================");
System.exit(0);
}
private void sendMessage2Topic(String msg) throws Exception{
// Provide the details of remote JMS Client
Properties props = new Properties();
props.put(Context.PROVIDER_URL, "mq://x.x.x.x:7676");//I use my server's IP
// Create the initial context for remote JMS server
InitialContext cntxt = new InitialContext(props);
System.out.println("Context Created");
// JNDI Lookup for TopicConnectionFactory in remote JMS Provider
TopicConnectionFactory qFactory = (TopicConnectionFactory)cntxt.lookup("TestTopicConnectionFactory");
// Create a Connection from TopicConnectionFactory
Connection connection = qFactory.createConnection();
System.out.println("Connection established with JMS Provide ");
// Initialise the communication session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the message
TextMessage message = session.createTextMessage();
message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
message.setText(msg);
// JNDI Lookup for the Topic in remote JMS Provider
Topic topic = (Topic)cntxt.lookup("TestTopic");
// Create the MessageProducer for this communication
// Session on the Topic we have
MessageProducer mp = session.createProducer(topic);
// Broadcast the message to Topic
mp.send(message);
System.out.println("Message Sent: " + msg);
// Make sure all the resources are released
mp.close();
session.close();
cntxt.close();
}
}
But I get the following error:
Exception in thread "main" javax.naming.NoInitialContextException:
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:662)
at
javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
at
javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
at javax.naming.InitialContext.lookup(InitialContext.java:411) at
seclient.SeClient.sendMessage2Topic(SeClient.java:64) at
seclient.SeClient.main(SeClient.java:45) Java Result: 1
Please, say what is wrong with my code/actions.
EDIT: I changed password in gf - configuration - server config - JMS hosts - default_JMS_host and added to the code
props.put(Context.SECURITY_PRINCIPAL, "admin");
props.put(Context.SECURITY_CREDENTIALS, "xxxxxx");
But same result.
you need to set the value for the variable CLASSPATH: From your Glassfish lib folder and From your Glassfish modules folder ;c:\Glassfish\lib*;c:\Glassfish\modules*;
i am learning JMS tried a simple example below but it gives error
package pointToPoint;
import javax.naming.InitialContext;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.QueueSession;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
public class Receiver
{
public static void main(String[] args) throws Exception
{
// get the initial context
InitialContext ctx = new InitialContext();
// lookup the queue object
Queue queue = (Queue) ctx.lookup("queue/queue0");
// lookup the queue connection factory
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
lookup("queue/connectionFactory");
// create a queue connection
QueueConnection queueConn = connFactory.createQueueConnection();
// create a queue session
QueueSession queueSession = queueConn.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
// create a queue receiver
QueueReceiver queueReceiver = queueSession.createReceiver(queue);
// start the connection
queueConn.start();
// receive a message
TextMessage message = (TextMessage) queueReceiver.receive();
// print the message
System.out.println("received: " + message.getText());
// close the queue connection
queueConn.close();
}
}
error message:
Exception in thread "main" javax.naming.NoInitialContextException: 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(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.lookup(Unknown Source)
at pointToPoint.Receiver.main(Receiver.java:22)
can anyone please help me with this.
The answer is in the stack trace. In a stand-alone application, you should pass an environment (implementation, urls, etc) to the InitialContext. Inside a J2EE container like JBoss, your code will work.
This should help:
NoInitialContextException error
What the responder above meant was that the tutorial would help you send messages to a receiver on the same application server. A lot more is needed for remote lookups