Pages

Showing posts with label EJB3. Show all posts
Showing posts with label EJB3. Show all posts

Wednesday, June 15, 2011

EJB3 Method Invocation Timeouts

I have an application calling a remote method on a stateless session bean. This mehtod performs a whole heap of JPA transactions and thus can take quite some time to execute. The exact time is dependent on parameters passed in but mostly the call times out before the method can complete execution.

Something strange I noticed was that the JBoss TM doesn't actually stop the remote method, which continues execution (usually until completion) but only times out and aborts the method call. I would have thought the manager would want to interrupt any active thread that is running within a transaction that has timed out. But it seems you can control the two timeouts separately.

To control the EJB method timeout set the transaction timeout to a higher value. This can be done on a per method basis by annotating the method with

        @org.jboss.annotation.ejb.TransactionTimeout(600) // eg: a 10 minute timeout.

Or to apply the timeout setting to the entire bean:

        @ActivationConfigProperty(propertyName="transactionTimeout", propertyValue="600")

For bean managed transactions you can set the timeput pn the UserTransaction as follows:

        UserTransaction ut = (UserTransaction)ctx.lookup        ("java:someApp/someBean/SomeTransaction");
        ut.setTransactionTimeout(600);
        ut.begin();
        ...
        ut.commit();



To set the read timeout for remote method invocations in JBoss (6), update the following line in <JBoss home>/server/default/deploy/ejb3-connectors-jboss-beans.xml with:

        </parameter>
        <parameter>socket://${hostforurl}:${port}?timeout=600000</parameter>
        <parameter>

Thursday, February 10, 2011

J2EE Overview

Yes, there are so many other sites out there that provide J2EE Overviews but this is probably the most breif but yet complete one you'll find.

J2EE defines standards for developing multitier enterprise applications. It simplifies enterprise applications by basing them on standardised, modular components, and providing a set of services to those components. It handles many details of application behaviour automatically, without requiring complex programming.

Enterprise JavaBeans
EJB is a standard distributed object framework and component model. It defines several types of components: session beans, entity beans, message driven beans, which simplify application development by concealing application complexity and enabling the component designer to focus on business logic.

Servlets and JSPs
Servlets and Java Server Pages are complementary APIs, both providing a means for generating dynamic web content. Servlets are Java programs implementing the javax.servlet.Servlet interface and running in a Web/App server's servlet engine. JSPs contain a mixture of HTML and java scripts, JSP elements, and directives, and are compiled into Servlets by the JSP engine.

JDBC
JDBC is a set of interfaces allowing Java applications to access any database.

RMI
RMI is an API which allows Java objects to communicate remotely with other objects. Its equivalent from OMG is CORBA.

IDL
IDL is a standard platform-independent language used to define interfaces that object implemnetation provide and client objects call. It allows java objects to communicate with other objects in any language.

JMS
JMS API is a messaging standard that allows J2EE components to create, send, receive, and read messages. It enables distributed communication between components. The addition of the JMS API enhances the J2EE platform by simplifying enterprise development, allowing loosely coupled, reliable, asynchronous interactions among J2EE components and legacy systems capable of messaging.

JTA
JTA allows J2EE components to perform distributed transactions.

JavaMail
JavaMail API allows Java components to send and receive emails.

JAXP (includes JAXB which is sometimes mentioned separately?)
Java API for XML Processing allows java applications to parse and transform XML documents.

JNDI
Java Naming and Directory Interface is a protocol which provides a standard API to access naming and directory services. It allows Java applications to find any necessary resource in a standard way.


Why use J2EE?
  • It is a standardised and reliable software architecture
  • that gives a lot of flexibility
  • is well documented,
  • with low level services already implemented.

Tuesday, June 29, 2010

Simple EJB3 Example

This post provides instructions on creating a simple Stateless Session Bean and a test client to see it working. It assumes Eclipase IDE and JBoss.

Create a new EJB project in Eclipse, called EJB3SessionBeanExample. Accept all project defaults.

Create 2 packages under the ejbModule directory: "bean" and "client"

Create the following classes under the bean folder:

IHelloBean

package bean;

import java.io.Serializable;

public interface IHelloBean extends Serializable {
  public void doSomething();
}

HelloBeanRemote

package bean;
import javax.ejb.Remote;

@Remote
public interface HelloBeanRemote extends IHelloBean {

}

HelloBeanLocal

package bean;
import javax.ejb.Local;

@Local
public interface HelloBeanLocal extends IHelloBean {

}

HelloBean

package bean;

import javax.ejb.Stateless;

/**
* Session Bean implementation class
*/
@Stateless
public class HelloBean implements HelloBeanRemote, HelloBeanLocal {

  private static final long serialVersionUID = 9184424076718418234L;
  public void doSomething() {
    System.out.println("Hello World!");
  }
}

Create the HelloBeanClient under the client folder:

package client;

import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class HelloBeanClient {
  public static void main(String[] args) {
    try {
      Properties props = new Properties();
      props.setProperty("java.naming.factory.initial",
          "org.jnp.interfaces.NamingContextFactory");
      props.setProperty("java.naming.factory.url.pkgs",           "org.jboss.naming");
      props.setProperty("java.naming.provider.url",
"127.0.0.1:1099");

      InitialContext ctx = new InitialContext(props);
      MyBeanRemote bean = (MyBeanRemote) ctx.lookup("MyBean/remote");

      bean.doSomething();
    } catch (NamingException e) {
      e.printStackTrace();
    }
  }
}

Right click on the EJB3SessionBeanExample project and select Run As -> Run on Server to publish to the server.

Once it is successfully deployed, right click on the HelloBeanClient class and select Run As -> Java Application. Accept any defaults and run it. You should see Hello World! printed to the console (or log C:\Apps\JBoss\jboss-5.1.0.GA\server\default\log depending on setup).

Tuesday, June 22, 2010

EJB Web Service Frustrations

It always amazes me how much time can be wasted trying to get some simple framework/middleware up and running. There is no actual coding involved, only googling error messages, substituting various pieces, plugging, patching, copying and pasting, etc, etc. And sadly today I am no where near as close to getting EJB3 web services working as I would like.

I wanted to get this working as there are a number of advantages to using EJBs as web services instead of POJOs:
  • A richer set of protocols are available
  • Gain access to framework like declarative security and transactions

So I began by googling to find a simple example that I could copy and paste into a few beans/classes and see some results without too much hassle. This was not a problem and I'd created a Remote Interface @WebService using @SOAPBinding(style=Style.RPC), declaring a couple of @WebMethod s, a stateless session bean implementing those methods, and a Client to test it within 10 minutes.

And then the fun began. It deployed with no problems but when I ran the client it crashed with some error about not being able to find some Xerces class. I googled that message and soon figured out that for some reason JBoss was not looking at the .../lib/endorsed/ folder where xercesImpl.jar was. Neither could I figure out how to make it look there so I just added the xercesImpl.jar as an external library. And that fixed that.

Running the client once more resulted in:

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.add(Unknown Source) at org.jboss.tutorial.webservice.client.Client.main(Client.java:45)Caused by: java.rmi.RemoteException: Call invocation failed; nested exception is: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage at org.jboss.ws.core.jaxrpc.client.CallImpl.invokeInternal(CallImpl.java:535) at org.jboss.ws.core.jaxrpc.client.CallImpl.invoke(CallImpl.java:275) at org.jboss.ws.core.jaxrpc.client.PortProxy.invoke(PortProxy.java:154) ... 2 moreCaused by: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage at javax.xml.soap.SOAPMessage.setProperty(Unknown Source) at org.jboss.ws.core.soap.SOAPMessageImpl.(SOAPMessageImpl.java:87) at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:169) at org.jboss.ws.core.CommonSOAP11Binding.createMessage(CommonSOAP11Binding.java:57) at org.jboss.ws.core.CommonSOAPBinding.bindRequestMessage(CommonSOAPBinding.java:157) at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:290) at org.jboss.ws.core.jaxrpc.client.CallImpl.invokeInternal(CallImpl.java:516) ... 4 more

This after much googling I concluded to be a SOAPMessage implementation bug, where the setProperty() method has been overridden in the abstract SOAPMessage class instead of the SOAPMessageImpl subclass where it should have been. The SOAPMessageImpl class is being loaded from rt.jar (Java 1.6) in the classpath instead of the JBoss one, and it calls the setProperty() method of the parent, which throws the UnsupportedOperationException. Hmmm... I'm not even sure if that makes sense as I have not looked into the source of the implementations but taken the explaination from another site. Note to self, check this.

I then proceeded to attempt to make JBoss look at the right jars by placing jbossws-native-core.jar and various other jbossws jars in the /lib/endorsed directory, adding them as external jars directly, and even taking some users' suggestions and using Java 5 instead of 6. Sadly none of this worked for me and I by the time I have given up for the day and set about documenting my experiences I have worked almost an 8 hour day (with liberal breaks for morning tea, lunch, a run, and a shower). I am no Eclipse guru and just switching to Java 5 took enough time by the time I figured out that I should really set the version of Java via the Project Properties -> Project Facets panel to make it take effect on the "java facet" version as well as the compiler compliance level. If it isn't set here the following error results:

"Java compiler level does not match the version of the installed Java project facet"

So a whole day has gone by and I have not managed to get a simple EJB3 web service example working. This is one thing that continues to frustrate me about software development - the amount of wasted time spent googling errors and trying random fixes in order to get something so simple working. Hopefully my next post will be an update on how I finally got a simple EJB3 web service working!

 
Powered by Blogger