Category: Java EE

Solving JAX-WS problems on Tomcat 7

When running JAX-WS applications on Apache Tomcat 7 you might encounter the following exception:

java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String;
	at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1077)

To solve this add the webservices-api-x.y.jar to the CATALINA_HOME/endorsed directory.

Do NOT add the webservice-rt-x.y.jar to the endorsed directory or you will encounter the following exception:

java.lang.NoClassDefFoundError: javax/servlet/ServletContext
	at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.<init>(WSServletDelegate.java:102)

Moving toward standard APIs

For my current client I am involved in the process of creating a list with allowed, deprecated and blacklisted frameworks and dependencies. I`ve noticed that there are a lot of internal projects that copy dependencies and framework choices from previous projects and are therefore using old and deprecated libraries. We are trying very hard to get projects to use standard APIs and get rid of the old stuff.

Frameworks like Spring, Google Guice, Seam, etc, are also moving toward standard APIs. Spring 3.0 embraces a lot of standards APIs like JSR303, JSR330, JSR317, which in my opinion is a good thing!

Why move to these new APIs?

It allows developers to focus on one API instead of learning a specific API for each framework. Switch or to other/competing frameworks or upgrading becomes easier. For example, the gap between Spring 3 and Java EE 6 (CDI + EJB3) has become much smaller due to these new standards. A good example were standardisation helps is the JSR 303 Bean Validation API which is supported by both Spring, Hibernate/JPA, JSF, etc.

Springmodules validation

In Spring 3 the JSR 303 Beans Validation API support was introduced which effectively replaces the springmodules validation project. Users of Spring 3 are encouraged to use this new JSR 303 Beans Validation API.

More information

When you want to leverage the standard API in your project, please have a look at the following articles:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation
http://www.openscope.net/2010/02/08/spring-mvc-3-0-and-jsr-303-aka-javax-validation/

Spring Dependency Injection annotations

Spring and Google have been working on a standardisation for Dependency Injection annotations, result: the JSR 330 specification. This is a standard API for doing annotation based dependency injection. Spring supports this API since Spring 3.0 (http://blog.springsource.com/2009/09/29/spring-framework-3-0-rc1-released/).

More information

Have a look at the following articles:

http://code.google.com/p/atinject/
http://ralf.schaeftlein.de/2009/11/19/spring-3-0-rc-2-and-jsr-330-dependency-injection-for-java/

Hibernate vs Java Persistence API

The Java Persistence API (JPA) was introduced as part of the Java EE 5 and EJB 3 specification. JPA is in a way the formalisation of Hibernate in a Java Specification (JSR). Since the makers of Hibernate were actively involved in this specification there are numberous of simularities between Hibernate and JPA.

Differences between Hibernate and JPA

JPA defines the standard API for using persistence in Java. You can use Hibernate as a JPA implementation. When using JPA developers can leverage the power of a standardised persistence API and still being able to use Hibernate specific functionality if required. But it opens up possibilities to move to EclipseLink or some other JPA implementation.

Hibernate 3.5 – JPA 2.0

In Hibernate 3.5 a lot of Hibernate subprojects have been merged back into the Hibernate core. This makes it easier to configure and use JPA in conjunction with Hibernate. The JSR 303 API was not officially included as a requirement for JPA 2.0 but Hibernate integrates nicely with the validation specification.

Conclusion

There are a lot of examples that demonstrate the benefits of using standard JSR APIs whenever possible. I would advice to use standard APIs whenever possible and only use specific framework functionality when the standards do not provide enough functionality.

Seam and EJB 3 integration on JBoss 5.1.0 GA

Last week a colleague (and good friend of mine) and I gave a JBoss Seam and Java ServerFaces training at company that creates tax automation products for local authorities. As a part of the training we prepared a workshop in which the participants had to build a webshop application. We decided to go with JBoss 5.1.0 GA combined with JBoss Seam 2.2 and EJB 3.0.

In this article I will share a few problems (and solutions) we encountered using Seam 2.2 and EJB 3 with JBoss 5.1.

JBoss startup bug in profiles.xml

First problem we encountered was with JBoss 5.1.0 GA. There seems to be a bug in the profiles.xml configuration that is packaged with JBoss AS that prevents the server from starting correct.

Here is the fix voor JBoss 5.1.0.GA. Open the file \jboss-5.1.0.GA\server\default\conf\bootstrap\profiles.xml
and locate the following xml fragment:

<bean name="AttachmentStore" class="org.jboss.system.server.profileservice.repository.AbstractAttachmentStore">
<constructor>
    <parameter><inject bean="BootstrapProfileFactory" property="attachmentStoreRoot" /></parameter>
</constructor>

Change it in:

<bean name="AttachmentStore" class="org.jboss.system.server.profileservice.repository.AbstractAttachmentStore">
<constructor>
    <parameter class="java.io.File"><inject bean="BootstrapProfileFactory" property="attachmentStoreRoot" /></parameter>
</constructor>
... // rest of the config without any change.

Also see: http://community.jboss.org/thread/2390

Seam EJB 3 integration

To get the Seam and EJB 3 integration working I spent almost 2 hours figuring out how to do it. Yes, it can be found in the documentation but it is not that clear as one would hope. Here are the steps to pull it of. I`m assuming that you have a separate jar project for your ejb code.

  1. Add an empty seam.properties to your ejb project.
  2. Add the seam inteceptor to the ejb-jar.xml
  3. Annotate your EJB SessionBeans with @Name
  4. Add the correct jndi-pattern for JBoss to the Seam components.xml

The ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
	version="3.0">
	<interceptors>
		<interceptor>
			<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
		</interceptor>
	</interceptors>
	<assembly-descriptor>
		<interceptor-binding>
			<ejb-name>*</ejb-name>
			<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
		</interceptor-binding>
	</assembly-descriptor>
</ejb-jar>

jndi-pattern

This is the part that took me way too long to figure out, you need to add the correct jndi-pattern in your seam components.xml (WEB-INF/components.xml). For JBoss this pattern is ear-name/bean-name/local (for local EJBs).

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
	xmlns:core="http://jboss.com/products/seam/core" xmlns:persistence="http://jboss.com/products/seam/persistence"
	xmlns:web="http://jboss.com/products/seam/web" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                 http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
                 http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">

	<core:init debug="false" jndi-pattern="ear-name/#{ejbName}/local" />
</components>

Using Seam injection for EJBs

If you annotate your stateless SessionBean, for example with @Named(“beanName”), you can start using the Seam injection in you web components. The EJB should look something like this:


@Stateless
@Name("productService")
public class ProductServiceImpl implements ProductService {
...
}

Have a you look at the web component example below, it gives an example on how to use the @In annotation to inject an EJB into your Seam component. Seam has a convention for knowing what bean you are referencing. If your bean variable instance name matches the @Named value, than the match can made by Seam. You can also explicitly specify the Bean name (@Named value) in the @In annotation. Make sure to also specify create=true on the @In or the injection will not work.


@Name("productListController")
@Scope(ScopeType.EVENT)
public class ProductListController {

	/**
	 * Injected EJB 3.0 Stateless SessionBean
	 * @see ProductServiceImpl
	 */
	@In(create=true)
	private ProductService productService;

	...
}

seam-gen

That should do the trick. If you get confused and don`t know what to do anymore. Generate an example application with seam-gen and look at the structure generated by seam-gen. Sometimes this helps ;-)

Get your app on the cloud with Google App Engine

I`m working on a small project that requires easy, cheap and reliable hosting for a Java web application. When searching for a good solution we ran into Google App Engine (GAE). GAE allowes you to run your Java applications on the Google Cloud.

Registering your application
You can signup for GAE via this link: http://appengine.google.com. Once you have registered you can create new applications and deploy them to your GAE space. When registering a new application you need to provide your application with a name. Once you have picked a name your application will be accessible through the following URL: your_app_name.appspot.com.

Developing Java application for GAE
If you want to develop Java application and upload them to the Google App Engine Cloud, you will have to install the App Engine SDK for Java first. You can find it here: http://code.google.com/intl/nl/appengine/downloads.html#Google_App_Engine_SDK_for_Java

JPA with App Engine
When you are in need of some data storage you can use either JDO or JPA. App Engine does not allow JDBC. Data storage is based on BigTable so there are some limitations to what you can do with JPA. Read this link if you want te get started using JPA on GAE. http://code.google.com/intl/nl/appengine/docs/java/datastore/usingjpa.html

Cavaets
You need to be aware that you application in running on a Cloud. There are some unexpected side effects because of this. When your application is idle for a period of time, the application will be taken offline to save resource. For example if you are running a Spring based Web application on GAE, the application context will be destroyed when your application is idle for longer than 2 minutes. The first request to hit your application will cause the Servlet & Spring context to be reinitialized, the request will be delayed with the reinitialization of the application. Fortunately there are work-arounds, you could schedule a cron you to do a keep-alive request on your application.

More information
If you want to learn more, see this short 10 minute demo from google on Youtube. http://www.youtube.com/watch?v=P3GT4-m_6RQ&feature=related

REST made easy with Java EE 6 and JAX-RS 1.1

In my previous post I wrote about Spring 3.0 and how Spring MVC enables REST services in Spring 3.0. Java EE 6 adds support for RESTfull services by adding JAX-RS to the specification. In this post I will show how JAX-RS 1.1 will make your life easy when writing RESTfull services for JEE 6.

GlassFish v3 is an open source application server and is the first compatible implementation of the Java EE 6 platform specification. To test the examples in this article I will assume that you use GlassFish (or any other JEE6 enabled application server) to run the examples.

Maven2 dependencies

Lets start with the Maven dependencies, you can add them all to the pom.xml of your war. I have also included Sun’s Maven2 repository for downloading the JEE6 dependencies like the javaee-api and Sun’s JAX-RS 1.1 implementation called Jersey.

Both dependencies are scoped as provided because GlassFish already ships with these libraries. In fact, my war file is not bigger than 22kb. JEE6 allowes developers to package full blown JEE application as a web archive file, there is no need for an enterprise archive anymore. This makes JEE6 applications really light weight.

JAX-RS RESTfull services in JEE6

JAX-RS supports configuration through annotations, just like the Spring 3.0 REST annotations. Annotations can be added to both classes and methods. Classes in JAX-RS can be POJO`s. One thing about JAX-RS is that it does not integrate well with other JEE specification, for example the JSR-330 annotations for dependency injection are not supported by JAX-RS (yet), but there is a workaround ;-)

Because of the flexibility of JAX-RS it is possible to annotate EJB SessionBean or CDI components with JAX-RS annotations. So when a bean with JAX-RS annotation is packaged in a war file, the annotations are automatically picked up by the JAX-RS implementation (Jersey in this case). Since EJB3.1 SessionBeans and CDI components support all of the dependency injection features offered by JEE6, JAX-RS now does too!

Below is an example JAX-RS annotated class. The goal of this RESTfull service is to expose two methods of the ProductService through a RESTfull interface. The ProductService is injected using the @Inject annotation.

In JAX-RS the @Path annotation is used to map an URI to a REST service. In the example below I’ve defined the @Path annotation on the class, this will map all the URIs starting with /product to this class. I also defined the @ManagedBean (CDI) annotation on the class for the @Inject to work properly.

There are two methods within the service which are annotated with @Path, @GET and @Produces. The @Path is the same as with the class, but in this case it maps URI’s to a method. The URI of a method is relative to URI specified in the @Path annotation
on the class. So the following URLs are mapped in this example:

  • /product/category/{categoryId} which returns all products in a category
  • /product/categories which returns all product categories
  • JAX-RS allowes for mapping HTTP methods like GET, PUT, POST and DELETE to Java methods with the @GET, @PUT, @POST and @DELETE annotations. In this example only the GET method is used. In RESTfull service the HTTP GET is used to retrieve data. To map a GET request to a method you can simply annotate a method with @GET.

    The @Produces annotation specifies the Mime-Type of the response data the methods produces. In this example the methods both produce XML data, therefore we need to set the Mime-Type to application/xml. When returning an Object from a method annotated with @Produces, JAX-RS trieds to find an appropriate converter to produces the output. In this case I will use JAXB will to marshall the Objects to XML (see below).

    JAXB marshalling

    In order for JAXB to marshall the Objects returned, we need to specify JAXB annotations on the Objects returned from the methods.
    In this example I’ve added @XmlRootElement to the returned Objects to simply marshall the entire Object to XML.

    Adding Jersey to the web deployment descriptor: web.xml

    For JAX-RS to work we still need to add a Servlet to the web.xml which maps URL’s to the services. In this case we need to add the JerseyServlet to the web.xml. In the servlet-mapping all /rest/ URL patterns are mapped to Jersey. We can access the REST services using the following URIs: /rest/product/etc.

    Conclusion

    When building RESTfull services on an JEE6 enabled application server, JAX-RS really makes things easy. You will have to decide for your specific case if you want to use Spring or JAX-RS.