I’m playing around with developing an application that integrates with the new Android Wear API. In my case I don’t want to perform certain actions locally if a wearable device is connected. So this is how you can detect if a device is connected. You would have this code included in the Main Activity of your primary (phone) application:
Configuring Dev and Prod Environments in Spring 3.1
Recently I have been exploring the Spring MVC Framework using on Spring 3.1. Based on my Grails experience I was surprised by the amount of manual configuration that is required. Nevertheless, I thought I would quickly share how to configure development and production environments in your application. Spring 3.1 introduced what is known as Profiles, which allow the developer to create various bean definitions to be used in different environments.
For instance, in order to use a different database for your dev and prod environments you could configure your sevlet-context.xml file with the following:
Then in your web.xml file you would have the following if you were deploying for the dev environment:
It’s just that simple…
Java Message Service
Java Message Service (JMS) is used for communication between software applications or software components. I have used JMS when I needed to send information to another component within the application but did not need to wait for an immediate response. There are two different ways that messages are sent and consumed.
- Synchronously. A subscriber or a receiver explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit.
- Asynchronously. A client can register a message listener with a consumer. A message listener is similar to an event listener. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener’s onMessage method, which acts on the contents of the message.
(Taken from Sun’s website)
Below is the code that configures the queues. This information is stored in a *-service.xml file so that the Application Server can recognize that mbeans are contained inside the file.
davis-jms-service.xml
<server>
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=BookRequestQueue">
<attribute name="JNDIName"> queue/davis/BookRequestQueue</attribute>
<depends optional-attribute name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=BookResponseQueue">
<attribute name="JNDIName">queue/davis/BookResponseQueue</attribute>
<depends optional-attribute- name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
</server>
This is the Service Locator that uses the JNDI names configured in the davis-jms-service.xml file to get access to the Connection Factory and the Queues.
ServiceLocator.java
/**
* Returns Queue Connection factory
* @return
* @throws ServiceLocatorException
*/
public QueueConnectionFactory getDavisConnectionFactory()throws ServiceLocatorException{
QueueConnectionFactory factory = null;
try{
Context context = getInitialContextLocal();
factory = (QueueConnectionFactory) context.lookup(“ConnectionFactory)”;
}
catch(Exception e){
throw new ServiceLocatorException(e);
}
return factory;
}
/**
* Returns reference to queue
* @return
* @throws ServiceLocatorException
*/
public Queue getBookRequestQueue() throws ServiceLocatorException{
Queue queue = null;
try{
Context context = getInitialContextLocal();
queue = (Queue) context.lookup(“queue/davis/BookRequestQueue”);
}
catch(Exception e){
throw new ServiceLocatorException(e);
}
return queue;
}
The BookListener.java class implements the onMessage method that is called whenever there is a message in the “queue/davis/BookRequestQueue” queue. It checks to see if the message received is of type TextMessage, if so, it will extract the text portion of the message and call the BookMgrDelegate to process the book.
BookListener .java
@MessageDriven(activationConfig =
{
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/davis/BookRequestQueue")
})
public class BookListener implements MessageListener {
public BookListener() { }
public void onMessage(Message message) {
TextMessage msg = null;
if (message instanceof TextMessage){
try{
msg = (TextMessage) message;
String strMessage = msg.getText();
BookMgrDelegate delegate = new BookMgrDelegate();
delegate.processBooks(strMessage);
}
catch(Exception e){
e.printStackTrace();
}
}
}
The BookMgrBean.java class is the actual call that inserts a record into the queue. The setupPTP function gets access to the Service Locator and then populates the needed Connections and Queues. The submitBooks function very simple uses the session to create a sender and receiver. It then sets the BookListener as the message listener for the receiver queue.
BookMgrBean.java
QueueConnection qConn = null;
QueueSession session = null;
Queue queue = null;
public void setupPTP() throws BookException {
try {
ServiceLocator locator = ServiceLocator.getInstance();
QueueConnectionFactory factory = locator.getDavisQueueConnectionFactory();
queue = locator.getBookRequestQueue ();
qConn = factory.createQueueConnection();
session = qConn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
qConn.start();
} catch (ServiceLocatorException se) {
throw new BookException(se);
} catch (JMSException je) {
throw new BookException(je);
}
}
public void submitBooks(String message) throws BookException {
setupPTP();
QueueSender sender = null;
try {
BookListener bkListener = new BookListener();
QueueReceiver receiver = session.createReceiver(queue);
receiver.setMessageListener(bkListener);
sender = session.createSender(queue);
TextMessage message = session.createTextMessage(message);
sender.send(message);
sender.close();
} catch (JMSException je) {
throw new BookException(je);
}
}
That’s it!
Basic Spring Transactions
Spring offers a few options when it comes to transaction management. I used the Programmatic Transaction option this was the easiest to implement in the architecture that I was working with. Here are the steps that I used.
First I modified the jboss-spring.xml file to include a bean reference to the JTA Transaction Manager.
jboss-spring.xml
<bean id=”transactionManager”
class=”org.springframework.transaction.jta.JtaTransactionManager” />
Then in the classes that I wanted to use transactions I added a reference to the bean as a property in the jboss-spring.xml file.
<bean id=”bookMgmtHandler” class=”com.davis.bo.BookMgmtHandler”>
<property name=”bookDAO” ref=”bookDAO” />
<property name=”transactionManager” ref=”transactionManager”/>
</bean>
I then needed to add some imports to the actual Java class that would contain the transactional references. The additional functions that I needed to add related to Spring transactions are highlighted in bold.
BookMgmtHandler.java
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class BookMgmtHandler {
BookDAO BookDAO = null;
BookDataAggregator BookDataAggregator = null;
private PlatformTransactionManager transactionManager = null;
private TransactionDefinition getDefinition() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition
(TransactionDefinition.PROPAGATION_REQUIRED);
return def;
}
public Book saveBook(Book book) throws BOOKException {
Book retBook = null;
TransactionStatus status = transactionManager.getTransaction(getDefinition());
// put a block for catching exceptions to rollback the transaction
try {
BookDAO.updateBook(book);
retBook = BookDataAggregator.getBook(book.getBookID());
}
catch (BOOKException be){
transactionManager.rollback(status);
throw be;
}
transactionManager.commit(status);
return retBook;
}
public void setTransactionManager(PlatformTransactionManager platformTransactionManager) {
this.transactionManager = platformTransactionManager;
}
}
And that’s it!