Showing posts with label JEE. Show all posts
Showing posts with label JEE. Show all posts

Sunday, May 9, 2010

Sunday, December 20, 2009

Spring 3.0 GA

Spring 3.0 is now GA. Spring has already fully demonstrated to be a successful alternative to EJB development. JEE 6 has learnt from Spring and simplified a lot enterprise Java development, becoming much more lightweight and usable. It shows that some good degree of competition can improve the market, but I hope Spring will keep following its own philosophy instead of trying too much to compete with JEE. the risk I see is that Spring could become too wide and difficult to understand.
Spring has demonstrated that the open community can produce better products than vendors' committees, so keep doing the good job of simplifying enterprise development.

Saturday, June 27, 2009

EJB 3.1 specs heading in the right direction

Since a long time EJB were loosing ground in favour of simpler and more effective programming models. specifically, Spring has become the leading framework to develop and deploy JEE applications.


For these reasons, a sense of urgency is pushing the new EJB specifications toward a massive simplification. This trend was clearly significant when the EJB 3.0 were introduced, and it is continuing now with the latest EJB 3.1.

Ken Saks, the Specification Lead for EJB 3.1, has written a nice summary of the hottest features. "A Sampling of EJB 3.1" shows you the most interesting news. Together with the upcoming Glassfish V3 , which is a very lightweight and OSGi based application server, the new specs can represent a quantum leap in terms of productivity and win back some developers.

It is difficult to predict if it is too late to regain developers' confidence and market quotas, but the combination of JEE 6 + EJB 3.1 + Glassfish V3 seems to be heading in the right direction: no overload of features but simplification.

Specifically, Ken Saks mentions:
  • Ease of Development: the ability to package enterprise bean classes directly in a .war file, without the need for an ejb-jar
  • No-interface View: you don't have to write interfaces if you don't need it
  • Simplified Packaging: You now have the option of placing EJB classes directly in the .war file, using the same packaging guidelines that apply to web application classes.
  • Singletons: A singleton is a new kind of session bean that is guaranteed to be instantiated once for an application in a particular Java Virtual Machine
  • Application Startup/Shutdown Callbacks: The introduction of singletons also provides a convenient way for EJB applications to receive callbacks during application initialization or shutdown

Simplification, is the way to go.

Wednesday, April 15, 2009

How to call a remote transactional Weblogic EJB from a Java client

My objective here is to show how to call a remote Weblogic stateless EJB from a Java client, then adding the ability to invoke multiple EJBs in a client-controlled transaction.

The code below is very simple and has been tested with BEA Weblogic Application Server 10.0 and developed with the Netbeans 6.1 IDE. The original requirement was to call Weblogic EJBs from Glassfish, using the Weblogic user transactions from the client code. Let's say there is the need to call several EJBs and to make it in a single unit of work, this is not usually a best practice, as client-controlled transactions are usually slower and lead to bad design. The best would be to expose a transactional service from Weblogic which wraps all the calls in one server-side unit of work, but it is not always feasible if we are not in control of the other side and this is also an example how to call a remote EJB from Java, if one removes the transactional code.

Anyway, let's have a look at our sample JEE 5 service (EJB 3), which is deployed in Weblogic:
package com.mt.ejb;
import javax.ejb.Stateless;

@Stateless(mappedName = "CalculatorBean")
public class CalculatorBean implements CalculatorRemote {
        public int add(int a, int b) {
        return a + b;
    }
}



Above is a trivial "hello world" EJB, implementing a Remote interface. The mappedName = "CalculatorBean" is a mandatory parameter for the @Stateless annotation if one wants the EJB to be remotely callable.

I deployed in Weblogic, Netbeans offers the ability to connect to a Weblogic server, even if the plugin has limited functionalities it gives me what I need and allows me to work from my favourite IDE and deploy from there.


Here comes the client code, which is more interesting:

package com.mt.client;

import com.mt.ejb.CalculatorRemote;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;

public class WeblogicTest {

    private final Logger log = Logger.getLogger(WeblogicTest.class.getName());

    public WeblogicTest() {
    }

    public void callRemoteEJB() {
        InitialContext context = null;
        UserTransaction transaction = null;

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        env.put(Context.PROVIDER_URL, "t3://localhost:7001");
        env.put(Context.SECURITY_PRINCIPAL, "weblogic");
        env.put(Context.SECURITY_CREDENTIALS, "weblogic");

        try {
            context = new InitialContext(env);
            transaction = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
            if (transaction != null) {
                log.info("in transaction context.");
                try {
                    CalculatorRemote calculator = (CalculatorRemote) context.lookup("CalculatorBean#com.mt.ejb.CalculatorRemote");
                    transaction.begin();
                    int result = calculator.add(3, 5);
                    transaction.commit();
                    log.info("add=" + result);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    try {
                        transaction.rollback();
                    } catch (Exception ex1) {
                        log.log(Level.SEVERE, "Can't rollback transaction.", ex1);
                    }
                }
            } else {
                log.info("transaction context is null.");
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        WeblogicTest test = new WeblogicTest();
        test.callRemoteEJB();
    }
}

It is necessary to add the CalculatorBean EJB jar file and the wlclient.jar to build the above client code. The wlclient.jar can be usually found into folder \server\lib of our Weblogic server.


Let's comment the main code sections.

First, I populate the connection properties:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic");
I look-up the initial context and get the UserTransaction from Weblogic's JTS:
context = new InitialContext(env);
transaction = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
I lookup and call the remote EJB by enclosing the method invocation in transaction:
CalculatorRemote calculator = (CalculatorRemote) context.lookup("CalculatorBean#com.mt.ejb.CalculatorRemote");
transaction.begin();
int result = calculator.add(3, 5);
transaction.commit();
The lookup string "CalculatorBean#com.mt.ejb.CalculatorRemote" makes the trick, it is the Weblogic syntax to identify the Bean and its Remote interface.

Of course, in this trivial case there are not any transactions, but I wanted to keep the example very simple. If the EJB was transactional, the call made use of the transactional context, while in this case it is simply ignored.