Step 3: Create a JMS Queue destination
Resources -> JMS -> Queues
Click on ‘New’ button
Click on ‘OK’ button
Type Queue for name
jms/Queue for JNDI name
Select InternalJMS as Bus name
Select Create Service Integration Bus destination as Queue name
Type q for Identifier
Click on ‘Next’ button
Click on ‘Finish’ button
Scroll down and click on ‘OK’ button
Click on ‘Save’ link
Friday, 11 November 2011
Configure JMS Resources and create Message Driven Bean in Websphere 7 (Step 2)
Step 2: Create a JMS Queue connection factory
Resources -> JMS -> Queue connection factories
Click on ‘New’ button
Click on ‘OK’ button
Type QueueConnection for Name
jms/QueueConnectionFactory for JNDI name
Select InternalJMS as Bus name
Click on ‘OK’ button (not shown in the screenshot)
Click on ‘Save’ link
Resources -> JMS -> Queue connection factories
Click on ‘New’ button
Click on ‘OK’ button
Type QueueConnection for Name
jms/QueueConnectionFactory for JNDI name
Select InternalJMS as Bus name
Click on ‘OK’ button (not shown in the screenshot)
Click on ‘Save’ link
Configure JMS Resources and create Message Driven Bean in Websphere 7 (Step 1)
Step 1: Create a service integration bus (SIB)
Log into Websphere Application Server 7 Admin Console
Service Integration -> Buses
Click on ‘New’ Button
Type InternalJMS, uncheck the Bus security checkbox and click on ‘Next’ button
Click on ‘Finish’ button
Click on ‘Save’ link
Click on ‘InternalJMS’ link
Click on ‘Bus members’ link
Click on ‘Add’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Finish’ button
Click on ‘Save’ link
Log into Websphere Application Server 7 Admin Console
Service Integration -> Buses
Click on ‘New’ Button
Type InternalJMS, uncheck the Bus security checkbox and click on ‘Next’ button
Click on ‘Finish’ button
Click on ‘Save’ link
Click on ‘InternalJMS’ link
Click on ‘Bus members’ link
Click on ‘Add’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Next’ button
Click on ‘Finish’ button
Click on ‘Save’ link
Friday, 4 November 2011
Aggregating MessageSource
I ran into this requirement in my recent task.
I need to overlay a war project onto another war project. Both war projects have their own messageSource bean defined. One uses the common ResourceBundleMessageSource. The other one uses a customized MessageSource, called RichTextMessageSource.
The idea is when a message code is required, search that message code in each of the MessageSources. If the message content is found, return that message. If no message content can be found through either of the MessageSources, throw a NoSuchMessageException.
The challenge lies in the identical bean name --- messageSource. If the bean name is changed, Spring is unable to load the MessageSource bean.
After doing online research, I decide to use an AggregatingMessageSource. (Enlightened by http://sacrephill.wordpress.com/2010/03/26/spring-aggregating-messagesource/)
Here is the source code of AggregatingMessageSource.java
In the spring application context file, first thing to do is rename the ResourceBundleMessageSource and RichTextMessageSource.
Then define the messageSource bean.
I need to overlay a war project onto another war project. Both war projects have their own messageSource bean defined. One uses the common ResourceBundleMessageSource. The other one uses a customized MessageSource, called RichTextMessageSource.
The idea is when a message code is required, search that message code in each of the MessageSources. If the message content is found, return that message. If no message content can be found through either of the MessageSources, throw a NoSuchMessageException.
The challenge lies in the identical bean name --- messageSource. If the bean name is changed, Spring is unable to load the MessageSource bean.
After doing online research, I decide to use an AggregatingMessageSource. (Enlightened by http://sacrephill.wordpress.com/2010/03/26/spring-aggregating-messagesource/)
Here is the source code of AggregatingMessageSource.java
/** * MessageSource implementation that delegates to any other * MessageSource beans. * e.g. if you have two MessageSources, 'messageSource1' and 'messageSource2', * if a message 'customer.firstname' is requested, it will: * * 1. If the message is found through 'messageSource1', return that message. * 2. If the message is found through 'messageSource2', return that message. * 3. Else, throw a NoSuchMessageException. * * @author Mingtao Sun */ public class AggregatingMessageSource implements MessageSource { /** A list of MessageSources */ private List messageSources = new ArrayList(1); /** @inheritDoc */ public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { for (int i=0; i<messageSources.size(); i++){ MessageSource messageSource = (MessageSource)messageSources.get(i); try{ String result = messageSource.getMessage(resolvable, locale); if (result != null){ return result; } }catch(NoSuchMessageException e){ //No message can be found in this messageSource //Move on to the next messageSource } } String[] codes = resolvable.getCodes(); throw new NoSuchMessageException(codes.length > 0 ? codes[codes.length - 1] : null, locale); } /** @inheritDoc */ public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { String result = getMessage(code, args, null, locale); if (result == null) { throw new NoSuchMessageException(code, locale); } return result; } /** @inheritDoc */ public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { for (int i=0; i<messageSources.size(); i++){ MessageSource messageSource = (MessageSource) messageSources.get(i); try{ String result = messageSource.getMessage (code, args, defaultMessage, locale); if (result != null){ return result; } }catch(NoSuchMessageException e){ //No message can be found in this messageSource //Move on to the next messageSource } } return null; } /** * Sets a list of MessageSources * @param messageSources a list of MessageSources to set */ public void setMessageSources(List messageSources) { this.messageSources = messageSources; } }
In the spring application context file, first thing to do is rename the ResourceBundleMessageSource and RichTextMessageSource.
<bean id="resourceMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>messages</value> …… </list> </property> </bean> <bean id="richMessageSource" class="com.smt.message.RichTextMessageSource"> …… </bean>
Then define the messageSource bean.
<bean name="messageSource" class="com.smt.message.AggregatingMessageSource"> <property name="messageSources"> <list> <ref bean="olcMessageSource"/> <ref bean="cicMessageSource"/> </list> </property> </bean>
Saturday, 29 October 2011
Create stateless session bean accessing database with JPA in Websphere 7
Create a Java project, named ‘ejb3-jpa’
Add runtime Websphere application server 7 to the build path
Under src, create a folder META-INF, under META-INF create persistence.xml
The contents of persistence.xml
jdbc/derby is the JNDI name for the datasource. It should be configured in Websphere application server already.
Openjpa.Log prints out the SQL. (Not working properly in WAS 7)
Openjpa.jdbc.synchronizeMappings creates the tables in the database if they don’t already exist.
openjpa.jdbc.MappingDefaults creates the foreign key constraints.
Create an entity bean: Person.java
Create a stateless session bean and its local interface: PersonManager.java and PersonManagerBean.java
Create a dynamic web project, named ‘ejb3-jpa-web’
Select ‘Websphere Application Server 7’ as the Target Runtime.
Include ‘ejb3-jpa’ project into the build path
Create a servlet: PersonServlet.java
Define the servlet in web.xml
Create an enterprise project, named ‘ejb3-ear’
Add ‘ejb3-jpa’ and ‘ejb3-jpa-web’ project into ‘ejb3-ear’
Add the ‘ejb3-ear’ project into the server, start the server
Right click on ‘WebSphere Application Server V7.0’, and click on ‘Properties’
Find out the port number
Go to http://localhost:PORT_NUMBER/ejb3-jpa-web/a.do
Replace PORT_NUMBER with the actual port number (i.e. 9084)
Check the database
Add runtime Websphere application server 7 to the build path
Under src, create a folder META-INF, under META-INF create persistence.xml
The contents of persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="unit"> <jta-data-source>jdbc/derby</jta-data-source> <properties> <property name="openjpa.Log" value="SQL=TRACE"/> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/> </properties> </persistence-unit> </persistence>
jdbc/derby is the JNDI name for the datasource. It should be configured in Websphere application server already.
Openjpa.Log prints out the SQL. (Not working properly in WAS 7)
Openjpa.jdbc.synchronizeMappings creates the tables in the database if they don’t already exist.
openjpa.jdbc.MappingDefaults creates the foreign key constraints.
Create an entity bean: Person.java
package entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="T_PERSON") public class Person{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name = "NAME") private String name; public Person() { super(); } public Person(String name) { super(); this.name = name; } public Person(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Create a stateless session bean and its local interface: PersonManager.java and PersonManagerBean.java
package session; import entity.Person; public interface PersonManager { public void save(Person person); } import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import entity.Person; @Stateless @Local(PersonManager.class) public class PersonManagerBean implements PersonManager { @PersistenceContext(unitName="unit") private EntityManager em; @Override public void save(Person person) { em.persist(person); } }
Create a dynamic web project, named ‘ejb3-jpa-web’
Select ‘Websphere Application Server 7’ as the Target Runtime.
Include ‘ejb3-jpa’ project into the build path
Create a servlet: PersonServlet.java
package web; import java.io.IOException; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import session.PersonManager; import entity.Person; public class PersonServlet extends HttpServlet { @EJB private PersonManager personManager; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { personManager.save(new Person("Sun")); } }
Define the servlet in web.xml
<servlet> <servlet-name>person</servlet-name> <servlet-class>web.PersonServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>person</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
Create an enterprise project, named ‘ejb3-ear’
Add ‘ejb3-jpa’ and ‘ejb3-jpa-web’ project into ‘ejb3-ear’
Add the ‘ejb3-ear’ project into the server, start the server
Right click on ‘WebSphere Application Server V7.0’, and click on ‘Properties’
Go to http://localhost:PORT_NUMBER/ejb3-jpa-web/a.do
Replace PORT_NUMBER with the actual port number (i.e. 9084)
Check the database
Friday, 28 October 2011
Three Ways to use an EJB
Define a stateless session bean
Way 1: Dependency Injection
beanName attribute (personBean) of @EJB annotation matches the name attribute of @Stateless annotation.
Way 2: Initial Context Look Up
@EJB annotation at class level registers the EJB with the beanName (i.e. personBean) in the JNDI ENC. The name attribute specifies the logical name (i.e. ejb/personManager) of the EJB in the JNDI ENC. This logical name can be looked up by InitialContext. (prefixed with “java:comp/env”)
Way 3: EJB Context Look up
With Ejb context lookup, the lookup string doesn’t need to be prefixed with “java:comp/env”
Now write a servlet to test
@Stateless(name="personBean") @Local(PersonManager.class) public class PersonManagerBean implements PersonManager { @PersistenceContext(unitName="unit") private EntityManager em; @Override public void save(Person person) { em.persist(person); } }
Way 1: Dependency Injection
@Stateless(name="dependencyInjectionService") @Local(Ejb3Service.class) public class Ejb3ServiceDependencyInjectionBean implements Ejb3Service { @EJB(beanName="personBean") private PersonManager personManager; @Override public void savePerson(Person person) { personManager.save(person); } }
beanName attribute (personBean) of @EJB annotation matches the name attribute of @Stateless annotation.
Way 2: Initial Context Look Up
@Stateless(name="initalContextService") @Local(Ejb3Service.class) @EJB(name="ejb/personManager", beanInterface=PersonManager.class, beanName="personBean") public class Ejb3ServiceInitialContextBean implements Ejb3Service { @Override public void savePerson(Person person) { PersonManager personManager = null; try { Context ctx = new InitialContext(); personManager = (PersonManager) ctx.lookup("java:comp/env/ejb/personManager"); } catch (javax.naming.NamingException ne) { throw new EJBException(ne); } personManager.save(person); } }
@EJB annotation at class level registers the EJB with the beanName (i.e. personBean) in the JNDI ENC. The name attribute specifies the logical name (i.e. ejb/personManager) of the EJB in the JNDI ENC. This logical name can be looked up by InitialContext. (prefixed with “java:comp/env”)
Way 3: EJB Context Look up
@Stateless(name="ejbContextService") @Local(Ejb3Service.class) @EJB(name="ejb/personManager", beanInterface=PersonManager.class, beanName="personBean") public class Ejb3ServiceEjbContextBean implements Ejb3Service { @Resource private EJBContext ejbContext; @Override public void savePerson(Person person) { PersonManager personManager = (PersonManager) ejbContext.lookup("ejb/personManager"); personManager.save(person); } }
With Ejb context lookup, the lookup string doesn’t need to be prefixed with “java:comp/env”
Now write a servlet to test
public class PersonServlet extends HttpServlet { @EJB(beanName="ejbContextService") private Ejb3Service service1; @EJB(beanName="initalContextService") private Ejb3Service service2; @EJB(beanName="dependencyInjectionService") private Ejb3Service service3; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { service1.savePerson(new Person("Sun8")); service2.savePerson(new Person("Sun9")); service3.savePerson(new Person("Sun10")); } }
Saturday, 22 October 2011
Difference between Stateless and Stateful session bean
Define a stateless session bean and a stateful session bean. The only difference is the @stateless and @stateful annotation.
Write a servlet to test.
Output:
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless2 result=2
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateful1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateful2 result=1
In this case, the same stateless session bean instance is used for both stateless1 and stateless2. The result is not predicable. Next time the output could be:
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless2 result=1
In this case, two different stateless session bean instances are picked up from the instance pool.
But the output for stateful session bean is always stable. Two different stateful session bean instances are always created.
@Stateless(name="stateless") @Local(Session.class) public class StatelessSessionBean implements Session { private int result; @Override public void add() { result++; } @Override public int get() { return result; } } @Stateful(name="stateful") @Local(Session.class) public class StatefulSessionBean implements Session { private int result; @Override public void add() { result++; } @Override public int get() { return result; } }
Write a servlet to test.
public class StatelessStatefulServlet extends HttpServlet { @EJB(beanName="stateless") private Session stateless1; @EJB(beanName="stateless") private Session stateless2; @EJB(beanName="stateful") private Session stateful1; @EJB(beanName="stateful") private Session stateful2; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { stateless1.add(); System.out.println("Stateless1 result="+stateless1.get()); stateless2.add(); System.out.println("Stateless2 result="+stateless2.get()); stateful1.add(); System.out.println("Stateful1 result="+stateful1.get()); stateful2.add(); System.out.println("Stateful2 result="+stateful2.get()); } }
Output:
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless2 result=2
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateful1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateful2 result=1
In this case, the same stateless session bean instance is used for both stateless1 and stateless2. The result is not predicable. Next time the output could be:
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless1 result=1
[18/08/11 11:49:22:828 EST] 0000001b SystemOut O Stateless2 result=1
In this case, two different stateless session bean instances are picked up from the instance pool.
But the output for stateful session bean is always stable. Two different stateful session bean instances are always created.
Subscribe to:
Posts (Atom)