/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.s1asdev.ejb.jms.jmsejb;
import java.util.Enumeration;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.EJBException;
import javax.naming.*;
import javax.jms.*;
import javax.transaction.UserTransaction;
public class HelloBean implements SessionBean {
private String str;
private SessionContext sc;
private boolean beanManagedTx;
private Queue queue;
private QueueConnectionFactory qcFactory;
private QueueConnection savedConnection = null;
private QueueSession savedSession = null;
public HelloBean() {}
public void ejbCreate(String str) throws RemoteException {
System.out.println("In ejbCreate !!");
this.str = str;
try {
Context context = new InitialContext();
beanManagedTx = ((Boolean) context.lookup("java:comp/env/beanManagedTx")).booleanValue();
if( beanManagedTx ) {
System.out.println("HelloEJB has BEAN MANAGED TRANSACTIONS");
} else {
System.out.println("HelloEJB has CONTAINER MANAGED TX");
}
String name = (String) context.lookup("java:comp/env/user");
Double d = (Double) context.lookup("java:comp/env/number");
System.out.println("Hello EJB - saying hello to " + name +
",number is " + d);
queue = (Queue) context.lookup("java:comp/env/jms/QueueName");
qcFactory =
(QueueConnectionFactory) context.lookup("java:comp/env/jms/MyQueueConnectionFactory");
} catch(Exception e) {
e.printStackTrace();
throw new RemoteException();
}
}
/**
* Send a message. In bmt case, create session BEFORE
* starting tx.
*/
public String sendMessage1(String msg) throws EJBException {
QueueConnection connection = null;
QueueSession session = null;
try {
connection = qcFactory.createQueueConnection();
session = connection.createQueueSession(true, 0);
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
sendMessageInternal(session, msg);
// Make sure calling commit when global tx is active
// results in the correct exception.
try {
session.commit();
throw new java.lang.IllegalStateException
("Didn't get session.commit exception");
} catch(javax.jms.TransactionInProgressException tipe) {
System.out.println
("Successfully got tx in progress excep " +
"after calling session.commit in a global tx");
} catch(javax.jms.JMSException jmse) {
System.out.println
("Got JMSException - it's also ok - " +
"after calling session.commit in a global tx");
} catch(java.lang.IllegalStateException e) {
throw new JMSException
("Should have gotten exception for tx-in-progress");
}
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
// Now make sure that even though the global transaction
// is over, calling commit results in an exception.
// since we're in an ejb.
try {
session.commit();
throw new JMSException
("Didn't get session.commit exception");
} catch(javax.jms.JMSException jmse) {
System.out.println("Successfully got session.commit " +
"exception in ejb");
}
try {
session.rollback();
throw new JMSException
("Didn't get session.rollback exception");
} catch(javax.jms.JMSException jmse) {
System.out.println("Successfully got session.rollback " +
"exception in ejb");
}
System.out.println("Sent message");
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
// no-op
connection.close();
try {
// no-op
session.close();
session.createObjectMessage();
throw new JMSException
("Didn't get expected illegal state exception");
} catch(javax.jms.IllegalStateException j1) {
System.out.println
("Successfully got illegal state exception " +
"when calling session method after close");
} catch(javax.jms.JMSException j2) {
throw new JMSException("Got wrong jmsexception");
}
try {
session.getMessageListener();
throw new JMSException
("Didn't get expected illegal state exception");
} catch(javax.jms.IllegalStateException j3) {
System.out.println
("Successfully got illegal state exception " +
"when calling session method after close");
} catch(javax.jms.JMSException j4) {
throw new JMSException("Got wrong jmsexception");
}
}
} catch(Exception ne) {}
}
return msg;
}
/**
* Send a message. In bmt case, create session AFTER
* starting tx. In cmt case, there won't be any
* difference between this method and sendMessage1
*/
public String sendMessage2(String msg) throws EJBException {
QueueConnection connection = null;
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
connection = qcFactory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, 0);
sendMessageInternal(session, msg);
session.close();
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
System.out.println("Sent message");
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
}
} catch(Exception ne) {}
}
return msg;
}
/**
* Create a session and store it as part of
* the ejb's state. Then send a message.
* Corresponding recv method will close the session.
*/
public String sendMessage3(String msg) throws EJBException {
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
savedConnection = qcFactory.createQueueConnection();
savedSession = savedConnection.createQueueSession(true, 0);
sendMessageInternal(savedSession, msg);
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
System.out.println("Sent message");
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception ne) {}
throw new EJBException(e);
}
return msg;
}
/**
* Receive a message. In bmt case, create session
* BEFORE tx start.
*/
public void receiveMessage1() throws EJBException {
QueueConnection connection = null;
try {
connection = qcFactory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, 0);
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
connection.start();
Message message = recvMessageInternal(session);
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
System.out.println("Received message " + message);
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
}
} catch(Exception e) {}
}
}
/**
* Receive a message. In bmt case, create session AFTER
* starting tx. In cmt case, there won't be any
* difference between this method and recvMessage1
*/
public void receiveMessage2() throws EJBException {
QueueConnection connection = null;
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
connection = qcFactory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, 0);
connection.start();
Message message = recvMessageInternal(session);
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
session.close();
System.out.println("Received message " + message);
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
}
} catch(Exception ne) {}
}
}
/**
* Receive a message using a session that was saved as
* part of the ejbs state. Then close the session
* and its connection.
*/
public void receiveMessage3() throws EJBException {
if( savedConnection == null ) {
System.out.println("saved connection is null");
return;
}
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
savedConnection.start();
Message message = recvMessageInternal(savedSession);
if( beanManagedTx ) {
sc.getUserTransaction().commit();
}
System.out.println("Received message " + message);
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception e) {}
}
}
/**
* Send a message but don't commit. sendMessagePart2
* will commit. This method will only work with
* when bean has bean managed tx.
*/
public String sendMessage4Part1(String msg) throws EJBException {
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
} else {
System.out.println("skipping sendMessage4Part1 b/c of CMT");
return "skipped";
}
savedConnection = qcFactory.createQueueConnection();
savedSession = savedConnection.createQueueSession(true, 0);
sendMessageInternal(savedSession, msg);
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception ne) {}
throw new EJBException(e);
}
return msg;
}
/**
* Commit send that occurred in sendMessage4Part1
*/
public String sendMessage4Part2(String msg) throws EJBException {
try {
if( beanManagedTx ) {
sc.getUserTransaction().commit();
System.out.println("Sent message " + msg);
} else {
System.out.println("skipping sendMessage4Part2 b/c of CMT");
return "skipped";
}
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception ne) {}
throw new EJBException(e);
}
return msg;
}
/**
* Send a message and then rollback. receiveMessageRollback
* should be called after this.
*/
public String sendMessageRollback(String msg) throws EJBException {
try {
System.out.println("In sendMessageRollback");
if( beanManagedTx ) {
sc.getUserTransaction().begin();
}
savedConnection = qcFactory.createQueueConnection();
savedSession = savedConnection.createQueueSession(true, 0);
sendMessageInternal(savedSession, msg);
if( beanManagedTx ) {
sc.getUserTransaction().rollback();
} else {
sc.setRollbackOnly();
}
System.out.println("Rolled back message");
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception ne) {}
throw new EJBException(e);
}
return msg;
}
/**
* Check to make sure the previous send was rolled back.
*/
public void receiveMessageRollback() throws EJBException {
try {
System.out.println("In receiveMessageRollback()");
QueueReceiver receiver = savedSession.createReceiver(queue);
System.out.println("Checking for message on " + queue);
Message message = receiver.receiveNoWait();
if( message != null ) {
throw new Exception("Shouldn't have gotten msg " +
message);
} else {
System.out.println("Successfully DIDN'T receive msg");
}
} catch(Exception e) {
e.printStackTrace();
throw new EJBException(e);
} finally {
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception e) {}
}
}
/**
* Receive a message but don't commit. recvMessagePart2
* will commit. This method will only work with
* when bean has bean managed tx.
*/
public void receiveMessage4Part1() throws EJBException {
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
} else {
System.out.println("skipping recvMessage4Part1 b/c of CMT");
return;
}
savedConnection.start();
Message message = recvMessageInternal(savedSession);
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception ne) {}
throw new EJBException(e);
}
}
/**
* Commit the receive that was done in recvMessagePart1
*/
public void receiveMessage4Part2() throws EJBException {
try {
if( beanManagedTx ) {
sc.getUserTransaction().commit();
System.out.println("Received msg");
} else {
System.out.println("skipping recvMessage4Part2 b/c of CMT");
return;
}
} catch(Exception e) {
e.printStackTrace();
if( beanManagedTx ) {
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
}
throw new EJBException(e);
} finally {
try {
if( savedConnection != null ) {
savedConnection.close();
savedConnection = null;
}
} catch(Exception e) {}
}
}
/**
* Tests doing a receive that depends on a send. They
* must be in separate transactions.
*/
public void sendAndReceiveMessage() throws RemoteException {
QueueConnection connection = null;
try {
if( beanManagedTx ) {
sc.getUserTransaction().begin();
} else {
System.out.println("Skipping sendAndReceive test b/c CMT");
return;
}
connection = qcFactory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, 0);
String msgText = "sendandreceive";
sendMessageInternal(session, msgText);
sc.getUserTransaction().commit();
System.out.println("Sent message " + msgText);
//
connection.start();
sc.getUserTransaction().begin();
recvMessageInternal(session);
sc.getUserTransaction().commit();
} catch(Exception e) {
e.printStackTrace();
try {
sc.getUserTransaction().rollback();
} catch(Exception ne) {}
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
}
} catch(Exception e) {}
}
}
/**
* Tests doing a send and receive where send is rolled back.
*/
public void sendAndReceiveRollback() throws RemoteException {
QueueConnection connection = null;
try {
if( beanManagedTx ) {
System.out.println("In sendAndReceiveRollback");
sc.getUserTransaction().begin();
} else {
System.out.println("Skipping sendAndReceiveRollback test b/c CMT");
return;
}
connection = qcFactory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, 0);
String msgText = "sendandreceiverollback";
sendMessageInternal(session, msgText);
sc.getUserTransaction().rollback();
System.out.println("Rolled back message send : " + msgText);
QueueReceiver receiver = session.createReceiver(queue);
System.out.println("Waiting for message on " + queue);
sc.getUserTransaction().begin();
Message message = receiver.receiveNoWait();
sc.getUserTransaction().commit();
if( message == null ) {
System.out.println("Successfully didn't receive msg");
} else {
System.out.println("Rollback exception -- received msg " +
message);
throw new Exception("Rollback exception -- received msg " +
message);
}
//
} catch(Exception e) {
throw new EJBException(e);
} finally {
try {
if( connection != null ) {
connection.close();
}
} catch(Exception e) {}
}
}
private void sendMessageInternal(QueueSession session, String msg) throws JMSException {
// Create a message producer.
QueueSender sender = session.createSender(queue);
// Send a message.
TextMessage message = session.createTextMessage();
message.setText(msg);
sender.send(message);
}
private Message recvMessageInternal(QueueSession session) throws JMSException {
// Create a message consumer
QueueReceiver receiver = session.createReceiver(queue);
System.out.println("Waiting for message on " + queue);
Message message = receiver.receive();
return message;
}
public void setSessionContext(SessionContext sc) {
this.sc = sc;
}
public void ejbRemove() throws RemoteException {}
public void ejbActivate() {}
public void ejbPassivate() {}
}