Now that Workshop 10.3 is available, I test drove the new JEE 5 support with a very basic EJB 3 scenario. Namely, create a remote stateless session bean and invoke it from a stand-alone java client. I stumbled around at first since my first guesses for using the new Workshop JEE5 feature support worked were incorrect. So I've decided to write up my experience in case it will help someone else. It turns out that JEE 5 really does simplify things, and overall I think it is a big improvement.
A few weeks ago WebLogic Server 10.3 (also known as WebLogic Server 10g Release 3) was released and Workshop for WebLogic 10.3 was also bundled with the full server installer. You can download it separately on the Developer Tools section on the OTN download site. Pieter Humphrey's entry on the tools blog that details lots of new features or Andrei Cioroianu's OTN article for a more thorough walk-through show-casing more features. In previous releases of Workshop, the wizards/tooling only supported EJB 2.1 development with WebLogic's EJBGen (or EJBDoclet based on XDoclet) even though WebLogic Server 10.0 and newer support JEE 5 and EJB 3.
Old School EJB 2.x
For review and comparison, consider the way I was familiar with in Workshop 9.2 through 10.2 to create a simple stateless session bean and client. Click the image to enlarge the screen captures.
- Create a new EAR project (EAR facet version 1.4 and WebLogic EAR extensions facet versioned to the release of the app server you are deploying to).
- Create a new EJB project (with EJB Module facet version 2.1 and WebLogic EJBGen Support facet version for your WLS release). On the next page in the wizard, do not select the client project option (in fact I do not think it will even let you).
- Go to the EJB project properties->WebLogic EJB->Jar settings - EJB client jar and indicate the location the client jar should be placed as an output of a build (try to use an absolute path here or it will place the jar relative to the current working directory).
- Create a session bean - typically right-click on the "ejbModule" source folder and select New->WebLogic Session Bean. This will open a wizard, which results in a stubbed out session bean. The bean has annotations for the weblogic.ejbgen package.
- During a project build (triggered by a deploy or an export), weblogic.EJBGen is invoked, which builds out all of the EJB plumbing for you (local, remote, home interfaces, classes, deployment descriptors, the ejb client jar, etc.).
- Develop a client class with a main method to invoke the session bean.
For an example of how to develop the the EJB 2.x client class, you can go look at the examples that ship with WLS. <SERVER_HOME>\wlserver_10.3\samples\server\examples\src\examples\ejb\ejb20\basic\statelessSession\Client.java. Essentially, it involves getting a JNDI context, finding the ejb home, creating an instance and narrowing that object....phew I'm tired just thinking about all of that. However, this model is fairly well known to enterprise java developers now.
New School EJB 3
I assumed the steps would be similar for JEE 5 and EJB 3, but I was a little off. I'll highlight the areas where it is different or non-intuitive in red.
- Create a new EAR project (EAR facet version 5.0 and WebLogic EAR extensions facet versioned to the release of the app server you are deploying to)
- Create a new EJB project (EJB Module facet version 3.0 and NO WebLogic EJBGen Support facet). Since we are planning to use the client without EJBGen, this time select the client jar option on the next screen in the wizard. This will result in another project being created just for the client interfaces and client code.
- You do not create a session bean using the menu New-> and navigating to WebLogic Session Bean, rather you simply create a basic interface for your EJB in the EJB Client project. You could place it somewhere else, such as the EJB Project, but since the EJB Client project is already on the classpath for the EJB project, putting the interface in the EJB Client is a nice way of packaging that interface so it can be easily referenced in other projects . Not using the menu or a wizard to create the session bean surprised me, but since JEE 5 and EJB 3 is so simple, it makes sense that you would not need a wizard.
- Create a class implementing that interface and annotate the class with @Stateless and @Remote. You could also annotate the interface with @Remote instead of the class. It's up to you. I prefer keeping all the EJB annotations in one file and keeping the interface clean. I find it easy to just use code-completion Ctrl-Space on the annotation which adds the import statement. In the @Stateless annotation, specify the mappedName attribute so you will know the JNDI name. The formula for the JNDI name is documented here. Basically it is mappedName#FullyQualifiedInterfaceName. So in my example the JNDI name would be HelloWorld#test.HelloWorld.
- Create the class with the main method that will invoke the session bean. There is no sample of this for EJB 3 in the examples, probably because it is so easy. I put this in it's own Java Project, but you could put it in the client project as well depending on your packaging structure. The code to do the invocation is so simple, no more home interfaces and narrowing, simply cast the returned object from the lookup to the interface and perform the invocation.
ic = getInitialContext();
HelloWorld helloWorld = (HelloWorld) ic.lookup(HELLO_WORLD_JNDI_NAME);
To actually run the Main method class in Workshop, I right click on the class in the Project Explorer and select Run As->Open Run Dialog. In the classpath tab, be sure to add the wlclient.jar file located here <SERVER_HOME>\wlserver_10.3\server\lib to the User Entries section and remove the WebLogic System Libraries from the Bootstrap Entries section. If you forget to remove the WebLogic System Libraries, you will get a stack like this: Exception in thread "Main Thread" java.lang.NoClassDefFoundError: weblogic/kernel/KernelStatus
If you put both the Main method and interface in the same jar file, you can invoke it with only 2 jars on the classpath, JEE doesn't get much simpler than this:
D:\TEMP\jeeclient>java -cp d:\wls103\wlserver_10.3\server\lib\wlclient.jar;HelloJava.jar test.TestClient
There may be better ways to go about this, and I'd love to hear about it if you've found a better approach or have comments on the approach I've described above. My Workshop 10.3 projects are available here with all my code. Simply File->Import->General->Existing Projects into Workspace->From Archive and give it a shot and enjoy much improved support for JEE 5 and EJB 3 in Workshop.