NullPointerException when creating connection from connection factory - java

I am trying to create a connection using connectionFactory.createConnection() method but it returns a null.
Below is my code :
#Stateless
public class test
{
#Resource(mappedName = "java:comp/DefaultJMSConnectionFactory")
private static ConnectionFactory connectionFactory;
#Resource(mappedName = "jdbc/JurassicParkCon")
private static Queue queue;
public static void main(String args[])
{
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
TextMessage message = null;
final int NUM_MSGS = 3;
try {
connection = connectionFactory.createConnection();
}
catch(Exception e){System.out.println("It is:"+e.getMessage());}
In the above code am only trying to create a connection but it returns NullPointerException. I have added a JMS resource through the admin console in GlassFish (name is jdbc/JurassicParkCon).
Recently only I started working with EJB's so I am not very familiar with errors. I have added the #Stateless annotation because there was a similar problem which was posted on StackOverflow and for that user adding the annotation worked but not for me.
What might be the problem here ?
Thank you for your time.

It won't work as a standalone application. You need to run it in a container.

Related

How to use oracle.tip.adapter.jms.JmsConnectionFactory;

Somebody helps me with code example of proper using oracle.tip.adapter.jms.JmsConnectionFactory.
This is connection factory for using JMS through JMSAdapter in Weblogic 12C.
Weblogic 12ะก connected to standalone ActiveMQ server through JMSAdapter. In JMSAdapter I created new outbound connection with jndi eis/ext/open under oracle.tip.adapter.jms.IJmsConnectionFactory (interface) with properties:
AcknowledgeMode = AUTO_ACKNOWLEDGE
ConnectionFactoryLocation = org.apache.activemq.ActiveMQConnectionFactory
FactoryProperties = BrockerURL=tcp://host:port;ThirdPartyJMSProvider=true
public class CustomJMSSelector {
private final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
private final static String JMS_FACTORY="eis/ext/open";
private static JmsConnectionFactory jmsConnectionFactory;
public static byte[] customSelectorConsumer(String correlationId) throws NamingException, ResourceException {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
Context ctx = new InitialContext(env);
jmsConnectionFactory = (JmsConnectionFactory) ctx.lookup(JMS_FACTORY);
I need to create session, consumer and consume message from queue using oracle.tip.adapter.jms.JmsConnectionFactory.
Unfortunately, oracle.tip.adapter.jms.JmsConnectionFactory doesn't implement javax.jms.ConnectionFactory. It implements oracle.tip.adapter.jms.IJmsConnectionFactory that extends oracle.tip.adapter.api.OracleConnectionFactory. I tried cast to javax.jms.Connection or to org.apache.activemq.ActiveMQConnectionFactory but got class cast exception. This connection is using by osb (proxy service, business service)
Assuming oracle.tip.adapter.jms.JmsConnectionFactory implements javax.jms.ConnectionFactory you can simply create a connection, session, and consumer like so:
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
...
public class CustomJMSSelector {
private final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
private final static String JMS_FACTORY="eis/ext/open";
private final static String QUEUE_JNDI_NAME="queue/jndi/name"; // the JNDI name of the queue
private static ConnectionFactory jmsConnectionFactory;
public static byte[] customSelectorConsumer(String correlationId) throws NamingException, ResourceException {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
Context ctx = new InitialContext(env);
jmsConnectionFactory = (JmsConnectionFactory) ctx.lookup(JMS_FACTORY);
Queue queue = (Queue) ctx.lookup(QUEUE_JNDI_NAME);
Connection connection = jmsConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(queue);
Message message = consumer.receive();
// do something with the message
connection.close();
}
}
This is a very simple bit of code with no real resource management. In a production use-case you'd want to use a pooled connection factory so that you aren't actually creating and closing a physical connection for every message you receive.

Error in ConnectionFactory in rabbitmq

I used RabbitMQ in my java application . I used amqp-client3.1.3.jar. But getting java.lang.NoClassDefFoundError: com/rabbitmq/client/ConnectionFactory while deploying my code in jboss. How to resolve?
public class Exapmle {
static Connection connection = null;
static Channel channel = null;
static ConnectionFactory factory = null;
private Example() {
try {
factory = new ConnectionFactory();
//--code goes here---//
}
I had written the same code in ejb which is scheduled and deployed in wildfly. I saw the resolution of adding the dependency to jboss setup. How should i do this?

Restart embedded broker in unit test : VMTransportServer already bound

I'm trying to write a test that simulates a "broker down" phase.
Therefore I want to
start a local broker
send message1
stop the broker
send message2 (which will of course not arrive)
start the broker again
send message3
According to http://activemq.apache.org/how-do-i-restart-embedded-broker.html it is recommended to init a new BrokerService to start the broker again.
So the code looks (almost) like this:
private BrokerService _broker;
private void startBroker() throws Exception {
_broker = new BrokerService();
_broker.addConnector("vm://localhost?broker.persistent=false");
_broker.start();
_broker.waitUntilStarted();
}
private void stopBroker() throws Exception {
_broker.stop();
_broker.waitUntilStopped();
}
#Test
public void publishMessagesWithServerBreakdownInBetween()
throws Exception
{
startBroker();
... send and receive message (works fine)
stopBroker();
... send message (fails of course)
startBroker(); // this fails with java.io.IOException: VMTransportServer already bound at: vm://localhost?broker.persistent=false
... send and receive message
}
The problem is already mentioned as comment in code:
The restart of the broker fails due to the error : java.io.IOException: VMTransportServer already bound at: vm://localhost?broker.persistent=false
I found a similar problem at ActiveMQ forum (http://activemq.2283324.n4.nabble.com/VMTransportServer-already-bound-td2364603.html), but in my case the hostname isn't null.
Another idea was to set 2 different broker names, but that also didn't help.
What am I doing wrong?
You want to control what the VM Transport does by telling it not to try and create a broker for you since you are adding it to an already created broker. The rest is pretty simply then:
public class AMQRestartTest {
private BrokerService broker;
private String connectorURI;
private ActiveMQConnectionFactory factory;
#Before
public void startBroker() throws Exception {
createBroker(true);
factory = new ActiveMQConnectionFactory("failover://" + connectorURI);
}
private void createBroker(boolean deleteAllMessages) throws Exception {
broker = new BrokerService();
TransportConnector connector = broker.addConnector("vm://localhost?create=false");
broker.setPersistent(false);
broker.start();
broker.waitUntilStarted();
connectorURI = connector.getConnectUri().toString();
}
#Test(timeout = 60_000)
public void test() throws Exception {
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("test");
MessageConsumer consumer = session.createConsumer(queue);
MessageProducer producer = session.createProducer(queue);
connection.start();
broker.stop();
broker.waitUntilStopped();
createBroker(false);
producer.send(session.createTextMessage("help!"));
Message received = consumer.receive();
assertNotNull(received);
assertTrue(received instanceof TextMessage);
}
}

Java - Code Coverage

I have a method in one of the classes in my code base that for the life of me, I cannot get into with my junit tests.
Basically this class is called when I request a database connection, if a stale connection is returned, a new connection is established
Here is the snippet of the mthod in my class (trimmed down for this purpose)
public class TCSOracleDataSourceWrapper extends OracleDataSource {
private static final int STALE_CONNECTION_EX_CODE = 17143;
private OracleConnectionCacheManager cacheManager;
private String cacheName;
/** Local log variable **/
private final Log logger = LogFactory.getLog(getClass());
/**
* Class constructor
* #throws SQLException
*/
public TCSOracleDataSourceWrapper() throws SQLException {
super();
}
private static final long serialVersionUID = 1L;
#Override
/**
* Get a connection but if the connection is stale then refresh all DB connections
*
*/
public final Connection getConnection() throws SQLException {
logger.debug("Retrieving a database connection from the pool");
Connection connection = null;
try{
connection = super.getConnection();
}
catch(SQLException e)
{
if(e.getErrorCode() == STALE_CONNECTION_EX_CODE)
{
logger.error("Stale Oracle connection found in the Connection Pool. Refreshing invalid DB connections.");
//refresh invalid connections
cacheManager.refreshCache(cacheName, OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS);
//now try to get the connection again
connection = super.getConnection();
}
else
{
throw e;
}
}
return connection;
}}
Any idea how I can ensure my junit tests execute the if statement?
I am currently using EasyMock and Powermock but I cannot find a way to get into this if statment using these tools
All help is greatly appreciated
Thank you
Damien
You should refactor your class to become a proxy for another data source, rather than inherit from one. This way you can easily inject into it a mock data source instead of the real one.
import javax.sql.DataSource;
public class TCSOracleDataSourceWrapper implements DataSource {
...
private DataSource wrappedDataSource;
...
public TCSOracleDataSourceWrapper(DataSource ds) {
wrappedDataSource = ds;
}
...
public final Connection getConnection() throws SQLException {
...
Connection connection = null;
try{
connection = ds.getConnection();
}
catch(SQLException e)
{
...
}
return connection;
}
}
One idea springs to mind: use aggregation rather than inheritance. This problem and others like it would go away because you can then mock the aggregated object to have whatever behavior you want. I don't see another way of getting in there right off hand. In fact, the name TCSOracleDataSourceWrapper already indicates that it's wrapping a data source (aggregation), when it actually isn't.
One quick workaround is to factor out the super.getConnection() call to a new private / protected method. Once you make that change it would be easy to mock the getBaseConnection method using power mock. This is short term fix, like the other answers suggest it is better to use delegation instead of inheritance for the wrapper implementation.
Connection getBaseConnection() throws SQLException {
return super.getConnection();
}
public final Connection getConnection() throws SQLException {
logger.debug("Retrieving a database connection from the pool");
Connection connection = null;
try{
connection = getBaseConnection();
}
catch(SQLException e)
{
if(e.getErrorCode() == STALE_CONNECTION_EX_CODE)
{
logger.error("Stale Oracle connection found in the Connection Pool. Refreshing invalid DB connections.");
//refresh invalid connections
cacheManager.refreshCache(cacheName, OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS);
//now try to get the connection again
connection = getBaseConnection();
}
else
{
throw e;
}
}
return connection;
}

Java WeakReferences = Understandingproblem (with HornetQ JMS Implementation)?

The code below does NOT work:
Cause:
I assume I tracked down the cause to:
http://community.jboss.org/thread/150988
=> This article says that HornetQ uses Weak References.
My Question:
Why does the code not run? (I have this code running with a slight different implementation, but the code blow fails repeatedly). My only guess is, that the
following references:
private Connection connection = null;
private Session session = null;
private MessageProducer producer = null;
are not regarded as strong references? (And this leads to the fact that the garbage collector removes the objects... But way arent they strong references?
Or is there another problem with the code (as said the code runs fine if I copy everything into one single method. But if I use the Singleton approach below the code does not work...) Another assumption was that it might have to do with ThreadLocal stuff, but I am using only a single thread...
The Code not working (stripped down):
public class JMSMessageSenderTest {
private static final Logger logger = Logger.getLogger(JMSMessageSenderTest.class);
private static JMSMessageSenderTest instance;
private Connection connection = null;
private Session session = null;
private MessageProducer producer = null;
private JMSMessageSenderTest() {
super();
}
public static JMSMessageSenderTest getInstance() throws JMSException {
if (instance==null) {
synchronized(JMSMessageSenderTest.class) {
if (instance==null) {
JMSMessageSenderTest instanceTmp = new JMSMessageSenderTest();
instanceTmp.initializeJMSConnectionFactory();
instance = instanceTmp;
}
} }
return instance;
}
private void createConnectionSessionQueueProducer() throws Exception {
try {
Queue queue = HornetQJMSClient.createQueue("testQueue");
connection = initializeJMSConnectionFactory();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(queue);
connection.start();
} catch (Exception e) {
cleanupAfterError();
throw e;
}
}
private void cleanupAfterError() {
if (connection != null){
try{
connection.close();
}catch(JMSException jmse) {
logger.error("Closing JMS Connection Failed",jmse);
}
}
session = null;
producer = null;
}
public synchronized void sendRequest(String url) throws Exception {
if (connection==null) {
createConnectionSessionQueueProducer();
}
try {
//HERE THE EXCEPTION IS THROWN, at least when debugging
TextMessage textMessage = session.createTextMessage(url);
producer.send(textMessage);
} catch (Exception e) {
cleanupAfterError();
throw e;
}
}
private Connection initializeJMSConnectionFactory() throws JMSException{
Configuration configuration = ConfigurationFactory.getConfiguration(null, null);
Map<String, Object> connectionParams = new HashMap<String, Object>();
connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5445);
connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.HOST_PROP_NAME, "localhost");
TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams);
ConnectionFactory connectionFactory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
// return connectionFactory.createConnection(login, password);
return connectionFactory.createConnection();
}
/**
* Orderly shutdown of all resources.
*/
public void shutdown() {
cleanupAfterError();
}
}
TestCode to run the code above
JMSMessageSenderTest jmsMessageSender = JMSMessageSenderTest.getInstance();
jmsMessageSender.sendRequest("www.example.com)");
jmsMessageSender.shutdown();
Gives the following error:
I'm closing a JMS connection you left open. Please make sure you close all JMS connections explicitly before letting them go out of scope!
The JMS connection you didn't close was created here:
java.lang.Exception
at org.hornetq.jms.client.HornetQConnection.<init>(HornetQConnection.java:152)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:662)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
Solution:
1.) You also have to Keep a reference to the ConnectionFactory (see the answer from Clebert below)
private ConnectionFactory factory = null;
2.) AND this code contains a severe hidden bug (that is not so easy to spot):
I initialized the Connection in the Constructor as well as in the createConnectionSessionQueueProducer() method. It will therefore override the old value and (as it is a Ressource that needs to be closed) will lead to a stale connection that HornetQ then will close and will then throw the error.
Thanks very very much! Markus
HornetQ will close the connection factory when the connection factory is released.
You need to hold a reference for the connection factory.
I also have similar issues. But it is not supposed to crash . Your implementation looks good. But only thing is that you are not closing the JMS connection , which in turn is getting closed by the hornetQ gc.
One thing probably wrong with the code is that you are calling cleanupAfterError() only after an exception. You should call the same method also after you have posted a message and a JMS connection is lying idle . Since you are just opening a connection to post a message and then not closing that connection unless an exception happens , Hornetq GC is finding that object and removing it while throwing this error.
Let me know if I missed something

Categories