Thursday Feb 16, 2006

Where is the NetBeans with JavaEE5 support avalaible?

I have seen some e-mails on mailing lists that NetBeans JavaEE daily builds aren't avalaible on netbeans.org. It's true and this issue should be already resolved. However, forget for Java EE 5 builds since these builds will not be avalaible any more, you should use 5.5 release from now.
What's happened with old builds and what's are new ones?
The development of the JavaEE5 stuff has been done on javaee5 branch. The builds from this branch was published on pages as JavaEE5 release. We created new branch with name release55 from javaee5 and merged some fixies and changes in J2EE modules from trunk. These, changes look horrible but it seems that everything was done successfully and we can start to implement new features on this branch. The upcomming NetBeans 5.5 release will be built from this branch.

Wednesday Feb 15, 2006

How to use date in persistence

In today's post I would like to describe how to use date data type in persistence class and then in queries. We very often use java.util.Date or java.util.Calendar objects in Java, these types can be used in persistence as well. In persistence class you can use Temporal annotation for specifying how the date property should be persisted. Without using Temporal annotation the property is persisted as TIMESTAMP. The TemporalType defines the mapping for temporal type, i.e. DATE, TIME, TIMESTAMP. The example is below:
     @Temporal(TemporalType.TIME)
     public Date getDueTime(){
       return dueDate;
     }
  
In this example dueDate will be persisted as java.sql.Date. Now, this property will be used in query. We should use setParameter in Entitymanager class and specify TemporalType for query like:
   List currentPlans = em.createQuery("SELECT a FROM Plan a WHERE a.creationTime  <= :time").
         setParameter("time", new Date(), TemporalType.TIME).getResultList();
   

Wednesday Feb 08, 2006

New code completion for Entity class in NetBeans

The new preview release of the NetBeans 5.5 will be released very soon. This new version is focused on support for Java EE5 especially. This changes require new features in code completion as well. We plan to support code completion for almost all annotations for persistance. For instance, you will be able to see tables that are in database that is specified in persistence file and the connection is registered in NetBeans. See snapshot:
The latest builds of NetBeans 5.5 with JavaEE5 support you can download from www.netbeans.org pages. There, click Downloads link and Development Builds of Upcoming Releases. On next page select Java EE 5 item for release version.

Tuesday Feb 07, 2006

Using enumeration in Entity class

In 5.0, the Java programming language gets support for enumerated types. In today's post I would like to show how to use enum in Entity classes. We should create new enumerated type firts:
    public enum AdvertisementState { OPEN, CLOSE, RESRVED}
  
This enum represents status of some advertisement. Then, we can create Entity class that represents advertisement:
  @Entity()
  public class Advertisement implements Serializable {
  private AdvertisementState state;

    @Enumerated(EnumType.ORDINAL)
    public AdvertisementState getState() {
        return state;
    }
You can use ORDINAL or STRING type. When you use ORDINAL type then columnt type is used INTEGER and for STRING the VARCHAR is used. Now, we can use the enum type for finding advertisements with OPEN status:
  em.createQuery("SELECT a FROM Advertisement a WHERE a.state = :state").
                  setParameter("state", AdvertisementState.OPEN).
                  setMaxResults(count).getResultList();
Using enum type is very easy, isn't it?

Wednesday Dec 21, 2005

Primary key generation in EJB 3.0blo

I and John Jullion-Ceccarelli wrote a tutorial about primary key generation in EJB 2.1. It was very pretty painful stuff, you should create table with appropriate data type column, use Object primary key and other. In EJB 3.0 is generation of PK different, it's easy to use. Let's go through all options that are for this in EJB 3.0. Primary key you can define in Entity bean with @Id annotation. There are five options for GeneratorType: NONE, AUTO, IDENTITY, SEQUENCE and TABLE. First one is NONE, it means that application is responsible for generation of primary key. Next one is AUTO that leaves the job to the container. This strategy indicates that a persistence provider should pick up appropriate strategy according to the database. It means that you need not setup your id and container generates it. I would like to describe SEQUENCE and TABLE strategy in more details below. SEQUENCE or IDENTITY strategy use a database sequence or identity column. I will show this strategy for Oracle database. We need to create new sequence with this command:
    CREATE SEQUENCE EMPL_ID INCREMENT BY 1 START WITH 100;
  
Then, this sequence can be used in entity bean like this:
     @Id(generate=GeneratorType.SEQUENCE, generator="EMPL_GEN")
     @SequenceGenerator(name="EMPL_GEN",sequenceName="EMPL_ID")
  
The sequenceName attribute specifies name of sequnce object in database. For TABLE strategy we should create table in database where primary keys will be stored:
     CREATE TABLE GEN_ID(
     GEN_KEY VARCHAR(20),
     GEN_VALUE INTEGER,
     PRIMARY KEY(GEN_KEY))
  
Then you can use this table in entity bean with TABLE generator strategy:
   @Id(generate=GeneratorType.TABLE,generator="ORDER_GEN")
    @Column(name="ID")
    @TableGenerator(name="ORDER_GEN",pkColumnName="GEN_KEY",
            pkColumnValue="ORDER_ID",allocationSize=1,
            initialValue=1,valueColumnName="GEN_VALUE",
            table=@Table(name="GEN_ID"))
 
All attributes are very intuitive and can be guessed from this sample. 
Generation of primary key in EJB 3.0 is simple, isn't it?

Monday Dec 19, 2005

EJB 3.0 client in J2SE project

Today, I would like to show how you can create client for EJB 3.0 in J2SE project. First, we will need to create a bean with remote interface. Since, we are using EJB 3.0 this is very simple. Create business interface with Remote annotation and then create bean's implementation class of your bean and specify JNDI name of this bean:
  @Stateless(name="ejb/ProcessHello")
  public class ProcessHelloBean implements org.netbeans.ProcessHello {

  public void String getHello(){
   ....
 
Now, we have two ways how to create client. First one is using Application Client Container (ACC) and second one is without that. What is advantage of the ACC? ACC can be seen as lightweight container that is responsible for security, naming, communication with application server and especially for injection. However, the worse of this approach is that you need run your application with appclient launcher. The client that uses ACC can be written like:
    @EJB(name="ejb/ProcessHello")
    private org.netbeans.ProcessHello hello;

    hello.getHello();
  
Then you need to run your client's jar with launcher appclient -client . The client launcher is located in bin directory of your application server. It's cool, but some smart user can ask what's about remote clients that aren't run on same machine as Glassfish? It's trivial task, you need to run package-appclient script that packs the application client container libraries and jar files into an appclient.jar file. This jar you can copied on remote server, unpack, change some properties and run your client. More info about this command is avalaible here. Now, let's develop EJB client without ACC. This client is similar as for EJB 2.1. It means first lookup bean interface and then invoke your business methods. You don't need to call create, ... and other lifecycle methods for the bean.
    InitialContext ctx = new InitialContext();
    Object obj = ctx.lookup("org.netbeans.ProcessHello");
    ProcessHello hello = (TestTableRemote)PortableRemoteObject.narrow(obj, ProcessHello.class);
    hello.getHello();
 
In this sample I used default JNDI name that is fully qualified classname of the remote business interface (3.0) or remote home interface (2.x). If you want to change the JNDI name use mappedName attribute for @Stateless.

Thursday Dec 15, 2005

Persistence in J2SE project

The big advantage of the EJB 3.0 is using entity beans out of container. This new feature will allow to test your business objects outside of application server. I would like to show how you can write simple J2SE project that uses EntityManager in NetBeans 5.0. Let's create new J2SE project in NetBeans.
  • We need to add persistence.xml file in META-INF directory in jar file. This can be simple done in NetBeans. Create new META-INF directory in src directory of your NetBeans project and add new persistence.xml into it. This file will be copied in correct place during building. In the properties.xml file we need to specify provider class name and persistence classes:
         <persistence xmlns="http://java.sun.com/xml/ns/persistence">
        <persistence-unit name="pu1">
            <!-- Provider class name is required in Java SE -->
            <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
            <!-- All persistence classes must be listed -->
            <class>persistence.Product</class>
            <properties>
                <!-- Provider-specific connection properties -->
                <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
                <property name="jdbc.connection.string" value="jdbc:mysql://localhost:3306/EJB"/>
                <property name="jdbc.user" value="blaha"/>
                <property name="jdbc.password" value="passw"/>
                <!-- Provider-specific settings -->
                <property name="toplink.logging.level" value="INFO"/>
            </properties>
        </persistence-unit>
    </persistence>
    
  • Add javaee.jar on project classpath. The jar is located in lib directory in Glassfish installation. Now, we can use persistence. The EntityManager need to be call first and then you can get EntityManager. See code snapshot:
    36 EntityManagerFactory emF = Persistence.createEntityManagerFactory("pu1");
    37         EntityManager em = emF.createEntityManager();
    38         EntityTransaction tx = em.getTransaction();
    39         tx.begin();
    40         Product product = new Product();
    41         product.setId(1);
    42         product.setPartNumber("ADSD-64464");
    43         product.setDescription("HAMMER");
    44         product.setPrice(12);
    45          em.persist(product); 
    46         tx.commit();
    47         
    48         // try to find product
    49         Query query = em.createQuery("select p from Product p where p.description =:descr");
    50         query.setParameter("descr","hammer");
    51         List results = query.getResultList();
    52         
    
  • Don't forget to add JDBC driver on project classpath.
  • The persistence projects must be run with -javaagent:${GLASSFISH_HOME}/lib/toplink-essentials-agent.jar. Add this option in project properties - Run - VM Options in NetBeans.

Wednesday Dec 14, 2005

How to use EntityManager API in web module

The javax.persistence.Entitymanager API is used for creating, finding and updating entity bean instances. I would like to show how EntityManager can be used in web module. I will focus only to Glassfish implementation. I know that Oracle App server uses a little bit different approach. They use EntityManager that is bind to java:comp/ejb/<module-name>/EntityManager.
First, some actions with EntityManager API are required to be used in a transaction, so the web module must manually demarcate the transaction using the UserTransaction API.
In objects that are managed by container like servlets, JSF beans and EJB bean you can use simple injection. Following sample explains how to use EntityManager in servlet:
     @PersistenceContext
     EntityManager em;
     @Resource
     UserTransaction tx;
     ....
     tx.begin();
     em.persist(new YourObject());
     tx.commit();
   
This approach can't be used in helper or business delegate classes. There, we should lookup theEntityManager and the UserTransaction using the JNDI binding:
    InitialContext ctx = new InitialContext();
    UserTransaction tx = (UserTransaction)ctx.lookup("UserTransaction");
    EntityManager em = em = (EntityManager) ctx.lookup("java:comp/env/persistence/EntityManager");
     tx.begin();
     YourObject o1 = em.merge(yourObject); // merge object to the new context
     em.remove(o1);
     tx.commit();
 
You'll need to define a persistence-context-ref for the component environment in which your class will run. It means add these elements in your web.xml file in web-app element:
  <persistence-context-ref>
  <persistence-context-ref-name>persistence/EntityManager</persistence-context-ref-name>
     <persistence-unit-name>unitName</persistence-unit-name>
  </persistence-context-ref>
 

Thursday Dec 08, 2005

Develop Custom Realm in NetBeans

I will write simple custom realm for Sun Application server in NetBeans. This realm will be used for authentication of users. I will implement very simple realm that will check password that are stored in Hashtable. I guess, extending this realm for using JDBC or other technology is easy task.
Implementation involves the following three steps:
  • Implement a JAAS LoginModule
  • Implement a Realm class
  • Configure the Realm and LoginModule into the server
The realm will be developed in NetBeans IDE. Final SimpleRealm project is avalaible here.Create new J2SE project and follow these steps:
  • Add appserv-rt.jar on project's classpath. This jar is located under lib directory in you App server.
  • First, create new class SimpleLoginModule in simplerealm package. This class must extend PasswordLoginModule. In this class we should implement authenticate() method that performs actual authentication. Our implementation calls method in Realm Class that did authentication itself. See attached sources for more info.
  • Create new class SimpleRealm in package simplerealm. The realm class is used to hook the custom realm into the Application Server. In this class the properties from domain.xml are read and authentication is performed.
  • Build project. In next steps we should register new realm in Application server.
  • I created targets that allow to register and delete realm in Application server. These tasks are in realm-targets.xml file in mentioned sources. Download sources and copy this file in project directory. You should copy login.conf, adminpw.txt and build.properties too in same directory. These files are needed for realm's targets.
  • Import realm targets in build.xml file. Open this file and add these lines in the file:
          <!DOCTYPE project [<!ENTITY RealmTargets SYSTEM "realm-targets.xml">]>
          .......
          &RealmTargets;
        
  • Run create-realm target. The target copies realm jar in App server directory and register realm
  • Logg in web console and go to Application server -- JVM Settings -- Path Settings and this ${com.sun.aas.installRoot}/domains/domain1/lib/SimpleRealm.jar in suffix classpath text field. Save and restart server.
  • Now, you can change realm config in your application and test new Simple realm. How you can change realm for web application? Very simple, open web.xml file and change realm-name value in SimpleRealm.
What's about debugging realm in NetBeans?
Start Application server in debug mode and put breakpoint in Realm class and attach debugger to port 9009. Then, you can login in your application and then debugg realm. ~

Tuesday Dec 06, 2005

How to use CMP beans with generated primary key

I saw a question about using CMP beans with generated primary key. Therefore, I decided to write one simple application that can explain how to use this feature. More info about generating primary key values in CMP beans is avalaible here here. I would like to note that the user should never rely on the internals of the container code. And if the user chooses to use a generated PK for CMP, it means they do not care about the value, and should not try to access it (other than as an Object).
In this post we will develop EJB module that creates product and purchase order. See Entity relationship diagram:
  • Create requested tables with following DDL:
          CREATE TABLE PRODUCT(
          ID BIGINT(19) NOT NULL,
          PART_NUMBER VARCHAR(19) UNIQUE NOT NULL,
          DESCRIPTION VARCHAR(25),
          PRICE FLOAT,
          PRIMARY KEY (ID),
          INDEX PART_NUMBER (PART_NUMBER)
          );
          
          CREATE TABLE PURCHASEORDER(
          ID BIGINT(19) NOT NULL,
          CUSTOMER VARCHAR(20) NOT NULL,
          PRODUCT_ID BIGINT(19) NOT NULL,
          AMOUNT FLOAT,
          PRIMARY KEY (ID),
          INDEX CUST (CUSTOMER),
          FOREIGN KEY (PRODUCT_ID) REFERENCES PRODUCT(ID))
       
    Primary key column should be mapped to column with NUMERIC data type with a precision of 19 or more.
  • Generete CMP beans from database and make changes that are described in above tutorial.
  • Add session facade bean and implement business method that creates order:
          public void createProduct(String partNr, String description, float price) throws EJBException {
            try {
                productHome.create(partNr,description, new Float(price));
            } catch (CreateException ex) {
                ex.printStackTrace();
                throw new EJBException(ex.getMessage());
            }
           }
    
           public void createOrder(String customer, String partNr, float amount) throws EJBException {
            try {
                ProductLocal product = productHome.findByPartNumber(partNr);
                purchaseHome.create(customer,new Float(amount),product);
            } catch (FinderException ex) {
                ex.printStackTrace();
                throw new EJBException(ex.getMessage());
            }catch(CreateException ex){
                ex.printStackTrace();
                throw new EJBException(ex.getMessage());
            }
        }  
      
  • Write client or JUnit tests and check the bean's functionality. Sources and tests are avalaible here.

Monday Dec 05, 2005

LDAP authentication in Sun Application server

Today, I would like to describe the steps to enable LDAP authentication in web module that is deployed in Sun Application server. Authentication is the way an entity determines that another entity is who it claims to be.
Very important for understanding security for SJAS is Realm. A realm, also called a security policy domain or security domain, is a scope over which the server defines and enforces a common security policy. In practical terms, a realm is a repository where the server stores user and group information. The Application Server comes pre-configured with three realms: file (the initial default realm), certificate, and admin-realm. In this post we will add and setup new ldap realm.
I will use open source implementation of the Lightweight Directory Access Protocol server that is avalaible here.
  • First, we should create new user. I created users.ldif file with one entry that represents user:
         dn: uid=blaha,ou=people,dc=netbeans,dc=cz
         uid: blaha
         givenName: blaha
         objectClass: top
         objectClass: person
         objectClass: organizationalPerson
         objectClass: inetorgperson
         sn: blaha
         cn: Petr Blaha
         userPassword: {SSHA}Z9RXgOsVA6395NtLw6ot7XjkO3dJAeUIqDdWdA==
       
    The entry should have defined uid attribute. The container will search entry according to this attribute during authentication.
  • Add this entry in ldap server, execute folowing command:
    ldapadd -x -D "cn=Manager,dc=netbeans,dc=cz" -W -f users.ldif
  • Open web admin console (bu default http://localhost:4848) and go to Security -- Realms page and click New button. Specify name, class name should be com.sun.enterprise.security.auth.realm.ldap.LDAPRealm and add these properties:
    directory: ldap://localhost:389 (change to right name)
    base-dn: ou=people,dc=netbeans,dc=cz (base distinguished name it represents from whence the search will start)
    jaas-context: ldapRealm (type of login module to use for this realm. Use ldapRealm)
  • Create new web application. I will use form authentication method. Therefore, I created new login page contains HTML form with these fields:
        <form method="POST" action="j_security_check">
          Username: <input type="text" name="j_username"/>
    Password: <input type="password" name="j_password"/> <input type="submit" value="Submit"/>
  • Update web.xml file according to new realm:
    18 <security-role>
    19     <role-name>USER</role-name>
    20   </security-role>
    21 
    22   <security-constraint>
    23     <web-resource-collection>
    24       <web-resource-name>protected area</web-resource-name>
    25       <url-pattern>/index.jsp</url-pattern>
    26       <http-method>GET</http-method>
    27       <http-method>POST</http-method>
    28     </web-resource-collection>
    29     <auth-constraint>
    30       <role-name>USER</role-name>
    31     </auth-constraint>
    32   </security-constraint>
    33 
    34   <login-config>
    35     <auth-method>FORM</auth-method>
    36     <realm-name>ldaprealmperapp</realm-name><!-- name of LDAP realm-->
    37     <form-login-config>
    38       <form-login-page>/login.jsp</form-login-page>
    39       <form-error-page>/error.jsp</form-error-page>
    40     </form-login-config>
    41   </login-config>
    
  • Now you can test LDAP authentication.

Thursday Dec 01, 2005

Hibernate plugin for NetBeans 5.0

Many developers don't like EJB, JDO technologies and they are using other object/relational persistance and query service for Java like Hibernate. Hibernate lets you develop persistant classes following common Java idiom. The plugin for Hibernate in NetBeans was missing. Recently, I have seen on project of my colleague.
Petr Zajac develops xdoclet plugin for NetBeans that enables Attribute-Oriented Programming for Java. The plugin parses your source code and generates many artifacts such as XML and other stuff. Based on this plugin he did Hibernate plugin.
This plugin allows you to create new POJO beans, add relationships, fields, ....code completion
Of course, the plugin generate all requested configuration files without your endeavour. The plugin is avalaible in SourceForge. You can download sources and nbms here
. I would like to show more plugin's functionality in some next post.

Wednesday Nov 30, 2005

Web service client in EJB module in NetBeans 5.0

I'm working on one J2EE application that has web service client in EJB module. However, NetBeans 5.0 doesn't support web service client for EJB. Since NetBeans uses Ant as build tool is very easy to add this missing feature in NetBeans. We should changes build.properties and add new target in build.xml file. Let's to add support for web service client in NetBeans. These steps create Static generated web service client (JSR-101) in your EJB module:
  • Add wscompile config file in src/conf directory. I created file with name CreditService-config.xml:
         <?xml version="1.0" encoding="UTF-8"?>
         <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
    	<wsdl location="http://localhost:8080/credit/CreditCardService?WSDL" 
              packageName="creditsystem.client"/>
         </configuration>
       
    Where location attribute represents location of the WSDL file and package is package where stubs will be generated.
  • Add these lines in project.properties file that is in nbproject directory:
         wscompile.classpath=${wscompile.tools.classpath}:${j2ee.platform.wscompile.classpath}
         wscompile.client.CreditCardService.features=strict,wsi
         wscompile.client.CreditCardService.package=creditsystem.client
         wscompile.tools.classpath=${java.home}\\\\..\\\\lib\\\\tools.jar
       
    First line setups classpath for wscompile, second one is wscompile options.
  • Now, add these target in your build.xml file:
        <target name="-pre-compile">
        <taskdef name="wscompile"
                 classname="com.sun.xml.rpc.tools.ant.Wscompile"
                 classpath="${wscompile.classpath}"/>
        <copy file="src/conf/CreditCardService-config.xml"
          tofile="${build.classes.dir}/META-INF/wsdl/CreditCardService-config.xml"/>
        <wscompile gen="true" base="${build.classes.dir}" keep="true" debug="true"
          config="${build.classes.dir}/META-INF/wsdl/CreditCardService-config.xml"
          classpath="${wscompile.classpath}"/>
        <wscompile gen="true" base="${build.dir}/ear-module" keep="true" debug="true"
          config="${build.classes.dir}/META-INF/wsdl/CreditCardService-config.xml"
          classpath="${wscompile.classpath}"/>
      </target>
       
    Here is one issue. You can see that similar task is invoked twice. The hack solves issue that EJB module can be included in J2EE application or can be standalone. When you build J2EE application with this EJB module then classes are built in different directory then for standalone module. I don't know how to resolve this issue in build.xml. Therefore, I call these two tasks.
  • Use this generated stubs and invoke web service operations.

Tuesday Nov 29, 2005

Transactions and JMS

I started to talk about JMS thence I might write a few sentences about transactions. Very often use case is that you deliver message and then this message is stored in database. How we can solve this. Should we use JTA for this?
I hope that reader knows that you mustn't use global transaction for consumer and producers. Why? Because, having all producers and all consumers participate in one global transaction would defeat the purpose of using a loosely coupled asynchronous messaging environment. JMS transactions follow the convention os separating the send operations from the receive operations. Which ways do we have for transactions with JMS?
  • If you are using only JMS in your transactions, you can create a JMS transacted session. A JMS transacted session supports transactions that are located within the session. A JMS transacted session's transaction will not have any effects outside of the session. For example, rolling back a session will roll back all sends and receives on that session, but will not roll back any database updates. Enable to this way, simple set first parameter to true in createSession method.
  • If you are mixing other operations, such as EJB, JDBC, with JMS operations, you should use a Java Transaction API (JTA) user transaction in a non-transacted JMS session. In this case you should first get lookup UserTransaction using JNDI and then start, perform desired operations and commit all like in this snapshot:
          UserTransaction txt = (UserTransaction) ctx.lookup("UserTransaction");
          txt.begin();
          // make JDBC stuff and send message
          txt.commit();
       
  • Use message driven beans with CMT. In this case enable container manage transaction in ejb-jar.xml file. Define Container as type of the transaction in this file and use Required for trans-attributes. These values are setup by default for all MDB that are created in NetBeans. Then you can use the MDB context in onMessage method like this:
        public void onMessage(Message aMessage) {
            try{
            if (aMessage instanceof ObjectMessage){
                // process message
                Order order = (Order)((ObjectMessage) aMessage).getObject();
                Connection conn = getDS().getConnection();
                // insert Order in DB
                ...................
            }else{
                logger.log(Level.SEVERE,"Only object messages are supported.");
            }
            }catch(SQLException ex){
               context.setRollbackOnly();
            }
        }
      
    I encountered one issue with this approach in Sun Aplication server. Messages are redelivered again and again. It means that you can flood your server with many messages. BTW, it's good test of Sun App server for DOS attack :-). I know that Jboss allows to setup of number of redelivering but I can't find it for Sun App server. Therefore, I suggest to use a little bit approach, throw EJB exception. What's happened when the database will be offline? Under container-managed transaction demarcation, upon receiving a runtime exception (EJBException extends Runtime exception) from a MDB the container roll-backs the container-started transaction and the message is delivered in dead queue. Below is same sample that throws EJBException.
        public void onMessage(Message aMessage) {
            try{
            if (aMessage instanceof ObjectMessage){
                // process message
                Order order = (Order)((ObjectMessage) aMessage).getObject();
                Connection conn = getDS().getConnection();
                // insert Order in DB
                ...................
            }else{
                logger.log(Level.SEVERE,"Only object messages are supported.");
            }
            }catch(SQLException ex){
               throw new EJBException(ex);
            }
        }
      

Monday Nov 28, 2005

Add other JMS subscriber in topic

On of the big advance of the topic is that other subscriber can be added very easy. For instance, we have existing order application that have one ProcessOrder subscriber and we would like to add other one. In this post I will show how you can add new subscriber in NetBeans 5.0, which changes should be done:
  • First, we create new EJB module with name Accounting. We would like to add new module that will make some order's accounting tasks
  • Add new MDB bean in this project. Since, we are using durable subscription, new MDB should have different clientId name in ejb-jar.xml than other one. The clientid should be unique.
  • Under Server resources node you can see new JMS Resources. However, we would like to use existing from Order module. Delete these resources.
  • We should change sun-ejb-jar.xml file as well. Open sun-ejb-jar.xml file and change these elements: jndi-name for mdb-connection-factory and message-destination-name. See code snapshot:
         <ejb>
          <ejb-name>AccountBean</ejb-name>
          <jndi-name>jms/ProcessOrderBean</jndi-name>
          <mdb-connection-factory>
            <jndi-name>jms/ProcessOrderDestinationFactory</jndi-name>
          </mdb-connection-factory>
        </ejb>
        <message-destination>
          <message-destination-name>AccountDestination</message-destination-name>
          <jndi-name>jms/ProcessOrderBean</jndi-name>
        </message-destination>
       
  • Add OrderLib project that includes Order TO on project's classpath.
  • Implement onMessage method.
  • Deploy and test JMS client. You should see that both EJB modules received order.
  • Account module sources are avalaible here.
About

pblaha

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks