Monday November 19, 2007
Java Persistence entites != EJB components

Recently a user sent a question to the ejb@glassfish.dev.java.net mailing list about an error he was seeing when trying to deploy an EJB JAR containing only Java Persistence API entities. Doing this causes a deployment error, and the user was confused. The reason for the error is that JPA entities are not EJB components, even though they were introduced in the EJB 3.0 specification.

I simply wasn't aware that POJOs annotated with @Entity are not considered EJB components in contrast to POJOs annotated with @Stateless for example.

The user mentioned reading articles and tutorials (vanity alert: definitely not my tutorials) about JPA entities that refer to them as EJB 3.0 entity beans, which is incorrect, if understandable. The reason why Java Persistence was part of the EJB 3.0 spec has nothing to do with the technology, and everything to do with the JCP procedures that govern the release of Java EE. Basically, when the architecture of Java Persistence was decided on by the EJB expert group (i.e. that entities would not be EJB components) it was too late to introduce a separate JSR. So, the choice was to wait until Java EE 6, or piggyback on EJB 3.0. Put another way, the choice was to frustrate and anger developers or confuse them.

So, kids, remember that Java Persistence API entities are not EJB components, and there's no such thing as EJB 3.0 entity beans.

Friday November 09, 2007
Java Persistence, implementations, and Java EE servers

We recently received some feedback asking:

At the J2EE for dummies level, I would like a diagram that shows a clear relationship between JPA and (EJBs, Hibernate, Toplink, ...). Maybe an onion model. As it is, JPA claims to have incorporated the best of several models but at the same time it seems to be a wrapper for the available models.

The Java EE architecture diagram here shows where the Java Persistence API fits into the Java EE concept of containers, but this might be confusing for some people, as it gets lost with all the other boxes full of acronyms. A more simple diagram might look something like this:

Here, an application I'm calling App 1 has three components, a web component, an EJB component, and a JPA component. It's deployed to a Java EE server, which runs on top of Java SE. So far, so good. When the JPA component is being used in the application, what's happening behind the scenes in the Java EE server?

Regardless of whether an enterprise bean or a web component is using the JPA component, the container (EJB or web) communicates with the configured JPA provider to access the underlying data. Because the Java Persistence API is required in Java EE 5 servers, every Java EE server has a default JPA provider. With GlassFish/Sun Java System Application Server, the default JPA provider is TopLink Essentials. TopLink Essentials is also the reference implementation of JPA.

There are other implementations of the Java Persistence API, though. Hibernate is a popular one. Another is OpenJPA. All of them, including TopLink, provide the baseline functionality of JPA, and also include implementation-specific features that go beyond the JPA specification. If your app uses one of these features, it's not portable across all JPA implementations. For example, if you use a Hibernate-specific feature, you can't deploy the application unchanged to a GlassFish server.

You can, however, configure your application to use an alternate JPA provider, provided that you make the alternate provider available to the Java EE server. The easiest way of doing this is to package the other provider's JAR with your application.

In this case, App 1 is bypassing GlassFish's default JPA provider, TopLink, in favor of Hibernate, which they have made available to GlassFish by packaging the Hibernate JAR with App 1, and configured their JPA component to use Hibernate. The EJB and web containers will use Hibernate to manage App 1's persistence unit.

Update: I should point out that if you want to avoid having to package the alternate JPA provider's JAR with each application, you can copy the JAR to GlassFish's INSTALL/lib directory and restart GlassFish so the JAR's classes are in GlassFish's runtime classpath.

Friday August 31, 2007
Minimum timeout interval for EJB Timer Service in GlassFish

I recently got some feedback from a Java EE 5 Tutorial user who saw some odd behavior when using a modified version of the EJB Timer Service example. The user's modified app attempts to create a repeating 3 second timer like this:

public void setTimer(long intervalDuration) {
  Timer timer = timerService.createTimer(0, intervalDuration,  "Created new timer");
}

And on the client:

long intervalDuration = 3000;
timer.setTimer(intervalDuration);

The user added a call to check the system time to measure the accuracy of the timeout in the @Timeout method in TimerSessionBean:

@Timeout
public void timeout(Timer timer) {
    logger.info(System.currentTimeMillis() + "Timeout occurred");
}

The user was surprised to see the interval timing as 7 seconds, not 3 seconds. I was surprised as well. I posed the question to the ejb@glassfish.dev.java.net mailing list, and heard back from Ken Saks, the EJB.next spec lead and the lead engineer for EJB 3 here at Sun:

The EJB Timer Service is not targeted towards very fine-grained timeouts, so there's a default minimum imeout interval of 7000 ms defined within Glassfish. That property can be changed via the minimum-delivery-interval-in-millis attribute in domain.xml.

Note that this is GlassFish-specific behavior. The EJB 3 spec doesn't define minimum timeout values, although it does say that the Timer Service is not designed for extremely precise operations required by real-time applications, as Ken pointed out in his response.

Update: I corrected Ken's email above to fix his typo of 7 ms to 7000 ms (that is, 7 seconds). domain.xml's DTD specifies a default value of 7000 ms for minimum-delivery-interval-in-millis.

Update 2: Update 4 of the Java EE 5 Tutorial contains an updated example with an 8 second/8000 ms timer, and a note on GlassFish's minimum default timeout value.

Friday May 11, 2007
Sun Web Developer Pack R2 and Tutorial available
The Sun Web Developer Pack (SWDP) R2 was released this last week, with updates to all the technologies that were in R1, and the new ROME Propono, a high-level API for working with web feeds (Atom, RSS, etc.). We also released an updated SWDP Tutorial (ZIP download), which details how to use the technologies and includes example projects that work in NetBeans and on the command line with Ant.
Monday April 02, 2007
Java EE Tutorial JAX-WS client examples and Application Server 9.1 Beta

If you are trying to use the Java EE 5 Tutorial with Application Server 9.1/GlassFish v2 Beta, you will encounter problems with the JAX-WS examples when running them in NetBeans. Here's the error message for simpleclient:

init:deps-jar:
wsimport-init:
Created dir:
C:\javaeetutorial5\examples\jaxws\simpleclient\build\generated\wsimport\client
Created dir: 
C:\javaeetutorial5\examples\jaxws\simpleclient\build\generated\wsimport\binaries
wsimport-client-check-HelloService:
wsimport-client-HelloService:
Consider using <depends>/<produces> so that wsimport won't do 
unnecessary compilation
parsing WSDL...
[ERROR] 
http://127.0.0.1:8080/helloservice/HelloService/__container$publishing$subctx/WEB-INF/wsdl/HelloService_schema1.xsd
unknown location
[ERROR] 
http://127.0.0.1:8080/helloservice/HelloService/__container$publishing$subctx/WEB-INF/wsdl/HelloService_schema1.xsd
unknown location

The error is due to the changes in JAX-WS 2.1 and JAXB 2.1, which are included in Application Server 9.1/GlassFish v2 Beta. For web service clients NetBeans uses a local copy of the WSDL to generate the artifacts needed to communicate with the service. The WSDL included with simpleclient uses the JAX-WS 2.0/JAXB 2.0 schema URI, as seen above in the error message.

The work-around is to retrieve a new copy of the WSDL. For example, for simpleclient:

  1. Deploy helloservice to Application Server 9.1/GlassFish v2 Beta.
  2. Open simpleclient in NetBeans.
  3. In the Projects pane, expand Web Service References and right-click on HelloService.
  4. Select Refresh Client.
  5. Right-click on simpleclient and select Run.

Refreshing the client WSDL in NetBeans

Another work-around is to follow the ant instructions for simpleclient.

We're working on a more permanent fix for the examples, and will release a new tutorial bundle as soon as we have a working solution.

Tuesday March 22, 2005
Bug in Duke's Bank example in the J2EE 1.4 Tutorial update 4, and workaround

There is a bug in NextIdBean.ejbCreate() in update 4 of the J2EE 1.4 Tutorial.

public Object ejbCreate() throws CreateException { return null; }

should be:

public String ejbCreate() throws CreateException { return null; }

This bug doesn't show up when using J2SE 5, only when using J2SE 1.4. J2SE 5 allows subclasses to have different return types. Look for a bug-fix update to the J2EE 1.4 Tutorial within a few weeks.

Thursday January 27, 2005
Feedback on J2EE Tutorial & deployment descriptors needed

For J2EE 5, Sun is putting a lot of effort into making enterprise applications easier to create, deploy, and use. Deployment descriptors consistently come up as a source of discontent with the J2EE development process. Right now we're scoping the J2EE 5 Tutorial, and would like your feedback on how the Tutorial should deal with deployment descriptors.

Of these three options, which do you prefer?

  1. No discussion of deployment descriptors, provide pre-assembled JARs/WARs/EARs
  2. Provide detailed instructions on assembling the JARs/WARs/EARs with a graphical tool like deploytool
  3. Provide both "fast track" instructions (option 1) and "slow track" instructions (option 2)

Related to this, what is your preferred development environment?

  1. IDE (like NetBeans, Java Studio Creator, Eclipse, JBuilder)
  2. command-line tools & text editor (vi, Emacs, TextEdit, etc.)
Wednesday December 22, 2004
J2EE 1.4 Tutorial update released

This release of the J2EE Tutorial is for Sun Java System Application Server 8.1 PE 2005Q1. The primary update was a rewrite of the Duke's Bank case study to use container-managed persistence for the entity beans. The previous version used bean-managed persistence.

For those who have wondered about how to use sequential primary keys in CMP beans without breaking CMP's database independence, Duke's Bank now uses a separate CMP bean/db table that retrieves and increments ids when creating other CMP beans. It's still not quite as easy as using sequences in the database itself, but it does the job, and it's fairly simple.

Look for some new advanced JAX-RPC examples in the next Tutorial release.