17 June 2011

Building and Running OpenJDK 7 on Mac OS X - A Breeze

Preparing a little for the Adelaide JUG meeting yesterday, where Java SE 7 was going to be the topic of discussion, I finally thought it was time to grab the OpenJDK 7 source, get it built and working on my Mac.

http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port

After checking off the pre-reqs, the process was as simple as following the small set of very clear instructions on the Wiki page.

The only small side excursion I had was that my bash environment had a JAVA_HOME env var set, which aborted the build at one point.  Unsetting that and restarting the build, it then ran flawlessly for about 30mins before out popped a shiny new Open JDK 7 build.

Having never manually installed a JDK on my Mac (Apple updates have served me well) the instructions for how and where to install it was very helpful. And so simple! Particularly with how it results in the new JDK being visible to the /usr/libexec/java_home utility:

sbutton:~ $ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
1.6.0_24-b07-334, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_24-b07-334, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.7.0, x86_64: "OpenJDK 7" /Users/sbutton/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
1.7.0, i386: "OpenJDK 7" /Users/sbutton/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home

Voila!

sbutton:~ $ export JAVA_HOME=`/usr/libexec/java_home  -v 1.7`
sbutton:~ $ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-sbutton_2011_06_16_11_39-b00)
OpenJDK 64-Bit Server VM (build 21.0-b15, mixed mode)  

 
Now looking forward to trying out some of the new language features with NetBeans 7.0.


All in all, a total breeze! Kudos to the OpenJDK Mac porters group.

14 June 2011

WebLogic Server: Listing Groups of an Authenticated User

Another question from a colleague today: "for a given authenticated user, how can I see what groups the user belongs to?" 

Yep, good question Pas. Not sure, but worth some time to find out.

Hunting through the WebLogic Security Documentation, I found a good description and diagram of how a Subject is related to a Principal.



A principal is an identity assigned to a user or group as a result of authentication. Both users and groups can be used as principals by application servers such as WebLogic Server. The Java Authentication and Authorization Service (JAAS) requires that subjects be used as containers for authentication information, including principals.

As part of a successful authentication, principals are signed and stored in a subject for future use.  

Any principal that is going to represent a WebLogic Server user or group needs to implement the WLSUser and WLSGroup interfaces, which are available in the weblogic.security.spi package.
Thus presumably, if you can get hold of the Subject, then you should be able to see the Principals associated with the User, of which some should reflect the Group(s) the User belongs to.

But how do you get the Subject?

I kept reading through documentation, but I couldn't see any really obvious description of where/how the Subject could be obtained. 

Then, after almost giving up and resorting to looking through the Javadoc, I found this small reference:
http://download.oracle.com/docs/cd/E17904_01/web.1111/e13711/thin_client.htm#i1030501

In Example 3-3, notice that the JSP is calling an API (request.getRemoteUser()) to get the name of the user that logged in.
A different API, weblogic.security.Security.getCurrentSubject(), could be used instead. To use this API to get the name of the user, use it with the SubjectUtils API as follows:

String username = weblogic.security.SubjectUtils.getUsername(
weblogic.security.Security.getCurrentSubject());
    
Note: In the actual doc, there's a missing opening parenthesis in the supplied code snippet.  I've added it in orange in the above.

Looking at the Javadoc, the weblogic.security.Security class has a static method that returns a javax.security.auth.Security object.

I also found a post from Edward Biemond here: http://blog.whitehorses.nl/2010/01/29/weblogic-web-application-container-security-part-1/ that discusses this area, from a slightly different more practical perspective perhaps.

With the Subject accessible and the description of the WLUser and WLGroup interfaces above, the group(s) an authenticated user belongs to can be readily discovered.
    
    import weblogic.security.Security;
    import weblogic.security.spi.WLSUser;
    import weblogic.security.spi.WLSGroup;
    ...
    private void doSubjectStuff(PrintWriter out, 
      HttpServletRequest request, 
      HttpServletResponse response) {

        Subject subject = Security.getCurrentSubject();
       
        StringBuffer groups = new StringBuffer();
        String user = null;
        boolean first = true;


        for(Principal p: subject.getPrincipals()) {
            if(p instanceof WLSGroup) {
                if(first) {
                    first=false;
                } else {
                    groups.append(", ");
                }
                groups.append(p.getName());
            } else if (p instanceof WLSUser) {
                user = p.getName();
            }
        }
       
        out.printf("<p>RemoteUser: %s, User: %s, belongs to: %s</p>",
                request.getUserPrincipal().getName(),
                user,
                groups);
    }



Calling this from a servlet, deployed within a simple web application that uses BASIC authentication mapped to a couple of WebLogic Server groups, the following output is displayed when the user "steve" logs in:
RemoteUser: steve, User: steve, belongs to: AppTesters, Deployers

Note, as Edmond also points out, the groups that are provided in the Subject are the WebLogic Server groups the user belongs to, and not the logical role-name defined in the web.xml file.
web.xml:

    <security-role>
        <role-name>ADMINS</role-name>
    </security-role>
weblogic.xml:

  <security-role-assignment>
    <role-name>ADMINS</role-name>
    <principal-name>AppTesters</principal-name>
    <principal-name>Administrators</principal-name>
  </security-role-assignment>
The primary new takeaway point I got from this was the use of the weblogic.security.Security class to obtain an instance of the current Subject.

07 June 2011

Using SLF4J with WebLogic Server Logging

Just recently, I needed to take a look at the SLF4J (Simple Logging Facade 4 Java) API, and more specifically, to how it could be employed on WebLogic Server.

Simple Logging Facade for Java

http://www.slf4j.org/

SLF4J follows the Commons-Logging model in that it provides a "Simple Logging Facade" with an API that can be used to insert log messages into application code, without specifying the specific Logging framework that is to be used. The actual work of capturing and emitting the log message is handled by "pluggable" SLF4J binding, which are added at deployment/runtime time (or server start) and handle the actual logging implementation work. There are pre-built bindings for the common logging frameworks such as JDK logging, Log4J, LogBack, as well as a simple Logging implementation that appears to simply print log messages to stdout.

Basic Problem

Having a look at a project that was using SLF4J with WebLogic Server, the question that came up was how could we direct the SLF4J logs into the standard WebLogic Server log facilities.

In it's basic form, with the slf4j-simple-1.6.0.jar binding being used, the SLF4J logs were not consistent with the rest of the WebLogic Server logs.

<Jun 7, 2011 3:22:04 PM CST> <Notice> <WebLogicServer> <BEA-000395> <Following extensions directory contents added to the end of the classpath:
/Users/sbutton/Projects/Domains/wls1035/lib/slf4j-api-1.6.0.jar:/Users/sbutton/Projects/Domains/wls1035/lib/slf4j-simple-1.6.0.jar>
<Jun 7, 2011 3:22:05 PM CST> <Info> <WebLogicServer> <BEA-000377> <Starting WebLogic Server with Java HotSpot(TM) 64-Bit Server VM Version 19.1-b02-334 from Apple Inc.>
<Jun 7, 2011 3:22:05 PM CST> <Info> <Management> <BEA-141107> <Version: WebLogic Server 10.3.5.0 Fri Apr 1 20:20:06 PDT 2011 1398638 >
. . .
. . .
<Jun 7, 2011 3:22:13 PM CST> <Notice> <WebLogicServer> <BEA-000331> <Started WebLogic Admin Server "myserver" for domain "mydomain" running in Development Mode>
<Jun 7, 2011 3:22:13 PM CST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING>
<Jun 7, 2011 3:22:13 PM CST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
14 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.oracle.demo.wlsslf4j.TestServlet - *** This is an info: class com.oracle.demo.wlsslf4j.TestServlet
14 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] WARN com.oracle.demo.wlsslf4j.TestServlet - *** This is a warning: class com.oracle.demo.wlsslf4j.TestServlet
14 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR com.oracle.demo.wlsslf4j.TestServlet - *** This is an error: class com.oracle.demo.wlsslf4j.TestServlet

The question was: without writing a specific WLS binding, is there a way to enable the SLF4J logs to be directed into the WebLogic Server logs so they are consistently formatted and able to be viewed in the WebLogic Server console with the rest of the logs?

One Solution

The solution was quite straightforward in the end, simply by combining two pieces of existing functionality:

1. The SLF4J distribution ships with a binding for JDK logging called slf4j-jdk14-1.6.0.jar. This results in the SLf4J logs being directed into the JDK logging framework.

2. WebLogic Server ships with a JDK logging handler which will pick up log messages emitted from JDK logging framework and direct them into the WebLogic Server logging system.

The weblogic.logging.ServerLoggingHandler is documented here: http://download.oracle.com/docs/cd/E14571_01/web.1111/e13739/logging_services.htm#CHDBBEIJ

To get it all working, all it required was making the relevant libraries available to WebLogic Server and wiring them together using a logging.properties file.

Copy Libraries into WebLogic Server

SLF4J basically comes as two components. There's the API which is used by applications, and then there's the bridgings that handle the actual production of log messages into the desired form.

To make SLF4J available to WebLogic Server, I employed the simplest way I know - copy them into the domain/lib directory. This has a certain set of limitations in terms of updating versions without a server restart, etc. but it's a really simple way to get things working in the first instance.

sbutton:~/Projects/Domains/wls1035 $ ls -l lib/
total 88
-rw-r--r-- 1 sbutton staff 702 6 Jun 13:15 readme.txt
-rw-r--r-- 1 sbutton staff 25496 7 Jun 15:19 slf4j-api-1.6.0.jar
-rw-r--r-- 1 sbutton staff 8887 7 Jun 15:34 slf4j-jdk14-1.6.0.jar

Create a logging.properties file

The logging.properties file is a standard way to control JDK logging. Since we have directed SLf4J logs into JDK logging framework by making the slf4j-jdk14-1.6.0 binding available, we can configure JDK logging to use the ServerLoggingHandler provided by WebLogic Server, so as to direct its logs into the WebLogic Server logging system.

The JDK logging framework and its configuration options are all well documented, starting from Nov 2001 here: http://download.oracle.com/javase/1.4.2/docs/guide/util/logging/overview.html

Here is the logging.properties file that was used:
####
# Specify the handlers to create in the root logger
handlers = weblogic.logging.ServerLoggingHandler

# Register handlers for the com.oracle.demo package and its child loggers
com.oracle.demo.handlers = weblogic.logging.ServerLoggingHandler

# Do not send the org.hibernate.validator log messages to the root handler
com.oracle.demo.useParentHandlers = false

# Set the default logging level for the root logger
.level = ALL
com.oracle.demo.level = ALL

# Set the default logging level for new ServerLoggingHandler instances
weblogic.logging.ServerLoggingHandler.level = ALL

To direct the JDK logging framework to use the logging.properties file, the standard System property java.util.logging.config.file is used. With WebLogic Server, this can be easily accomplished by setting the JAVA_OPTIONS System property with the corresponding value.



$ export JAVA_OPTIONS="-Djava.util.logging.config.file=/Users/sbutton/Projects/Domains/wls1035/logging.properties"


Start WebLogic Server and Observe

With the libraries copied into the domain/lib directory, the logging.properties file created and specified as $JAVA_OPTIONS, starting WebLogic Server should now allow the logs created via SLF4J to be directed into the WebLogic Server logging framework. This should let them be seen on stdout in a consistent form with the standard WebLogic Server log messages, as well as via the WebLogic Server console through it's log viewer.
SL4J logs in stdout
<Jun 7, 2011 3:52:01 PM CST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING>
<Jun 7, 2011 3:52:01 PM CST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
<Jun 7, 2011 3:52:07 PM CST> <Warning>
<com.oracle.demo.wlsslf4j.TestServlet> <BEA-000000> <*** This is a warning: class com.oracle.demo.wlsslf4j.TestServlet>
<Jun 7, 2011 3:52:07 PM CST> <Error> <com.oracle.demo.wlsslf4j.TestServlet> <BEA-000000> <*** This is an error: class com.oracle.demo.wlsslf4j.TestServlet>


SL4J logs in WebLogic Server console

30 May 2011

VI customizations for syntax coloring, auto-indenting and more

A colleague recently sent me a VIM resource file to configure how VIM displays code.

A small set of simple changes, but the effect is very nice and makes the casual viewing of code, scripts, etc. much nicer with line numbering, auto-indenting,  syntax color coding, etc.
$ cat ~/.vimrc

set shiftwidth=2 
set tabstop=2 
set number 
set ruler 
set expandtab 
set smartindent 
set autoindent 
set showmatch 
:syntax enable 
highlight Statement ctermfg=white
highlight PreProc ctermfg=3
set pastetoggle=<F10>

This is what it looks with a Java file:

Thanks Mark.

26 May 2011

Applying WLS CAT to WLS 10.3.3

To help answer an OTN question today regarding the use of the domain/lib directory on WLS 10.3.3, I went to use the CAT utility (as I've become accustomed) and then realized we'd only added it from the WLS 10.3.4 onwards.

As far as I'm aware, we don't make use of any newer APIs in WLS 10.3.4 within CAT, so I simply copied out the wls-cat.war file from a WLS 10.3.4 installation and deployed it to the WLS 10.3.3 domain I was using for the test.

The WLS CAT application deployed successfully and then seemed to work normally, letting me locate exactly where class I was using was being loaded from on WLS 10.3.3.

Of course this is totally unsupported, but if you're in need of WLS CAT on an earlier 10.3.x release and of the adventurous spirit, give it a shot.  You can always undeploy it if it doesn't work for you.

19 May 2011

Deploying a Random JSF 2.0 Example on WebLogic Server using Maven and NetBeans and Maven

I had a bit of a hunt around yesterday looking for some JSF 2.0 example applications to deploy.  I quickly came across a comprehensive JSF 2.0 tutorial @ http://www.coreservlets.com/JSF-Tutorial/jsf2/ published by Marty Hall.

For each of the tutorial sections on this site, the example code and pages that are used to demonstrate the concepts and discussion are published as accessible source code.

So I thought I'd try a few of them out with WebLogic Server 10.3.5. 

The examples I looked at didn't contain a build script, so I very simply converted them into Maven projects, which I then was able to open immediately in NetBeans (this feature rocks!).  I then built, packaged and ran the application on a WebLogic Server 10.3.5 domain, all from NetBeans.

All up, I'd say it tool ~2 mins to get the example loaded and building in NetBeans and deployed to  WebLogic Server.

It takes a lot more to describe it below than it does to actually do it.

Here's what I did to get the data-tables example to build, package and deploy to WebLogic Server. 

1. Download the zip file from http://www.coreservlets.com/JSF-Tutorial/jsf2/code/data-tables.zip.

2. Extract the zip file to a local directory, which produces:

/data-tables/WebContent
/data-tables/src
/data-tables/build

3. Generate a Java EE  Web Application using the Maven Archetype mechanism.  What a great feature this is in Maven. 

$ mvn archetype:generate
...
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
...
263: remote -> webapp-j2ee13 (-)
264: remote -> webapp-j2ee14 (-)
265: remote -> webapp-javaee6 (-)
266: remote -> webapp-jee5 (-)
...
Choose a number: 107: 266
Choose version:
1: 1.0
2: 1.0.1
3: 1.1
4: 1.2
Choose a number: 4:
Define value for property 'groupId': : coreservlets
Define value for property 'artifactId': : data-tables
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  coreservlets: :
Confirm properties configuration:
groupId: coreservlets
artifactId: data-tables
version: 1.0-SNAPSHOT
package: coreservlets
 Y: : y

4. Copy the WebContent and src directories from the data-tables example into the new Maven project structure.

$ cp -rp ~/Projects/Java/data-tables/WebContent/* src/main/webapp/
$ cp -rp ~/Projects/Java//data-tables/src/ src/main/java/


5. Start NetBeans and simply open the data-tables/pom.xml file to load the project into the IDE.



Click around and explore the project to get a sense of what it contains.




6. Add the jsf-api dependency to the POM so the ManagedBean classes can be compiled.

You can either manually add this direct to the pom.xml as:
    
    <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>


Or use the "Add Dependency" option on the project to search for it and enter it via a dialog:




7. Add a weblogic.xml deployment descriptor to reference the JSF 2.0 shared-library deployed on the WLS domain.

I simply coped in an existing version of the file I had used before.  You can also use the "New --> WebLogic --> WebLogic Descriptor" option in NetBeans to add it.


Add a library-ref to the jsf-2.0.war shared-library deployed on the WLS 10.3.4 domain.

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app>
  <context-root>/data-tables-1.0-SNAPSHOT</context-root>
  <library-ref>
    <library-name>jsf</library-name>
    <specification-version>2.0</specification-version>
    <implementation-version>1.0.0.0_2-0-2</implementation-version>
  </library-ref>

</weblogic-web-app>

8. Run the project, select the WLS 10.3.5 Server type and watch it get built and packaged via Maven and deployed by NetBeans.  This will start the WLS 10.3.5 server if necessary.





9. View the example application in a browser


Summary: there it is, a random JSF 2.0 example application, converted to a Maven project, opened in NetBeans and deployed to WebLogic Server 10.3.5, all in ~ 2mins.

First Adelaide Java User Group Session @ Oracle

Tonight sees the first time that the Adelaide Java User Group meeting is being hosted @ the local Oracle office.  

The session should be interesting with Derek Webber presenting on his area of expertise in Meta-programming with Groovy.

Meta-programming with Groovy

Meta-programming is a term to describe modifying code at runtime and is a very old idea in Computer Science. Groovy (now at 1.8) is a language that builds features directly on top of Java and aims to help developers be more productive. It’s meta-programming features provide a great number of opportunities to developers that are either really difficult to access or are all but impossible in plain Java. I will provide an overview of the Groovy Meta Object Protocol, along examples of what you can do with it. In particular it helps with:
  • easier reflection and adding behaviour dynamically
  • monkeypatching and extending existing 3rd party code
  • builders and domain-specific languages (DSLs)
For any local Adelaide folks interested in attending, the registration link is here: 
http://www.jugevents.org/jugevents/event/registration.form?event.id=38181

17 May 2011

Observing Bean Validation at JPA Level

A quick followup to yesterdays posting regarding the use of JSF 2.0, JPA 2.0 and Bean Validation.

To verify the validation of the constraints at the JPA level, and not at the JSF front end, I decided to add a simple Servlet which calls the WidgetFacadeLocal directly to create a new Widget entity.

This led to a small, interesting side excursion.

Since the NetBeans project was defined as a Java EE 6 Web Application, when the new Servlet was added, the default option was to not generate a web.xml descriptor to describe the Servlet configuration and mapping, and instead to define the Servlet using the @WebServlet annotation on the Servlet class itself.

@WebServlet(name = "TestValidationServlet", urlPatterns = {"/TestValidationServlet"})
public class TestValidationServlet extends HttpServlet {
    ....
}


Now this won't deploy in this form to WebLogic Server 10.3.4 since it doesn't yet implement the Servlet 3.0 specification and support @WebServlet.  But ... WebLogic Server has provided it's own specific annotation for Servlets since the 10.3 timeframe.

http://download.oracle.com/docs/cd/E17904_01/web.1111/e13712/annotateservlet.htm#i161636

Therefore to have this Servlet deploy and run on WebLogic Server, without introducing a web.xml file, the @WLServlet annotation can simply be added to the Servlet class, looking like this:

@WebServlet(name = "TestValidationServlet", urlPatterns = {"/TestValidationServlet"})
@weblogic.servlet.annotation.WLServlet(name = "TestValidationServlet", mapping = "/TestValidationServlet")
public class TestValidationServlet extends HttpServlet {
    ....
}

At compile time, add a reference to $WL_HOME/modules/com.bea.core.weblogic.web.api_1.4.0.0.jar to make the annotation available and it'll build and package successfully.

With that small excursion done, and the Servlet able to be deployed to WebLogic Server with the addition of the single @WLServlet annotation, the JPA validation can be tested.

This can be simply done again by injecting the stateless session bean WidgetFacadeLocal using an @EJB annotation, then creating a Widget with a known invalid property, and attempting to persist it through the session bean.  Any validation constraints that are violated will be detected and returned in an EJBException that can be checked, and displayed.

...
@EJB WidgetFacadeLocal widgetFacade;
...
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    ....
    try {      
        Widget widget = new Widget();
        widget.setName("My Widget");
        widget.setEmail("bogus.email.com");
        widgetFacade.create(widget);
   
    } catch (EJBException ejbex) {
        out.printf("<p>EJBException, caused by: %s</p>", ejbex.getCause().getClass().getName());
        if (ejbex.getCausedByException() instanceof ConstraintViolationException) {
            ConstraintViolationException cve = (ConstraintViolationException) ejbex.getCausedByException();
            out.printf("<p>Constraint Validations:</p>");

            out.println("<ul>");
            for(ConstraintViolation cv: cve.getConstraintViolations()) {
                out.printf("<li>%s, <b>%S</b>, %s, <span style='color: red;'>%s</span></li>",
                        cv.getRootBeanClass().getSimpleName(),           
                        cv.getPropertyPath(),
                        cv.getMessage(),
                        cv.getInvalidValue());
            }          
            out.println("<ul>");
        }          
    }    
}     

Here the Widget has an email address which is not valid, as well as missing the mandatory pricePerUnit property.

Deploying this to the WebLogic Server 10.3.4 domain used previously with JPA 2.0 enabled, and Bean Validation library added to the server classpath, the simple test shows that the Bean Validations are checked.   An exception is returned that contains the set of constraint violations that occurred, which can be displayed to a user.


This demonstrates the use of implicit Bean Validation through using JPA 2.0 running on WebLogic Server 10.3.4.

Again, the key is to firstly ensure that the Server ClassPath is set to include the following libraries to expose and enable JPA 2.0 and have the Bean Validation implementation be visible to the JPA 2.0 provider:
  • $WLS_HOME/modules/com.oracle.jpa2support_1.0.0.0_2-0.jar
  • $WLS_HOME/modules/javax.persistence_1.0.0.0_2-0-0.jar
  • $GF_HOME/glassfish3/glassfish/modules/bean-validator.jar
And secondly, ensure that either the default JPA provider on the domain is set to TopLink, or the provider is specifically set to be org.eclipse.persistence.jpa.PersistenceProvider in persistence.xml within the application.

16 May 2011

JSF 2.0, JPA 2.0 and Bean Validation on WebLogic Server

For some time now, I’ve been meaning to build a simple application to demonstrate the use of JSF 2.0, JPA 2.0 and Bean Validation with WebLogic Server 10.3.4.  But I hadn’t gotten around to it until I had a couple of hours free late last week.

Seeing as I didn’t have all that much time, I thought I’d try and repurpose the Java EE 6 CRUD (create-remove-update-delete) application that NetBeans generates for GlassFish 3.x, and see if I could get it to run on WebLogic Server. 

The short answer to that was a resounding yes, with only a few minor changes or tricks.

In this blog, I’m going to step through what I did and highlight the changes that I played around with in order to make it work.  I'm not going to make this a tutorial (at this point) since most of the steps that are required are simply using the NetBeans IDE and its wizards to generate the requisite components and pages.

Developing the Application
  1. The starting point for this app was a single table, Widgets, created in a local Derby database. 

  2. Using NetBeans 7.0, a new Java EE Enterprise Application was created, using Java EE 6 and targetted at the GlassFish 3.1 server installed with NetBeans.  This produces two child projects: a Web project and an EJB project.



  3. In the EJB project, use the "Entity Classes from Database" to generate a JPA 2.0 Entity from the Widget table.



    Worth pointing out here is the use of the Bean Validation specification to declare constraints on the various fields of the Widget entity. 

    I particularly appreciated the smarts NetBeans uses to provide a suggested @Pattern regular expression for an email field

    @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
    @Size(max = 100)
    @Column(name = "EMAIL")   
    private String email;

  4. Next, invoke the "Sessions Bean For Entity Classes ..." to generate a session facade with CRUD methods for the Widget entity. 



    Worth noting here are two points:   First, the use of a Generics based Abstract class for the base CRUD operations, which is then subclassed by the WidgetFacade session bean to work specifically with the Widget entity.  Second, the use of the JPA 2.0 Criteria API to build a number of queries in the base class.

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    This session bean is created with a local interface since the EJB 3.0 implementation in WebLogic Server requires the use of a business interface.

  5. In the persistence.xml file, a trick worth keeping in mind here which may save you some pain later is to explicitly specify the JPA provider to use.  This helps later on when you deploy the completed application to WebLogic Server, where the default JPA provider is Kodo/OpenJPA.  This can be overridden at the WLS domain level, but setting it in persistence.xml within the application itself is an easy way to do it now.

    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

    For more details on changing the default JPA provider for a WLS domain, see here:

    http://buttso.blogspot.com/2010/05/changing-default-jpa-provider-in.html

  6. With the EJB project now complete, the JSF pages can be generated for the application.  In the Web project, this is done using the "JSF Pages from Entity Classes ..." wizard. 



    What this wizard generates is a set of JSF pages to represent each of the CRUD operations, a Controller ManagedBean to handle the various tasks required by each of the JSF view pages and the data interactions (with paging) and a EJB 3.1 @Stateless session bean to act as a session facade on the Widget entity.

    The new EJB in WAR packaging option available with Java EE 6 is not yet available on WebLogic Server, so the first trick here is to change the Web project to use the session facade that has already been generated in the EJB project.  This is possible because the NetBeans wizards generate the same underlying code for the session facade whether it is for an EJB specific project or as part of the JSF Pages for Entity Classes wizard. 

    Delete the session bean bean in the Web project, then adjust the JSF controller to use the local interface for the session bean in the EJB project:

    //@EJB
    //private sab.demo.widget.service.WidgetFacade ejbFacade;
    @EJB
    private sab.demo.widget.service.WidgetFacadeLocal ejbFacade;

    Note that EJB 3.1 supports a No-Interface view of an EJB, which WebLogic Server doesn't yet support.  So here we have changed the injection point to use the Local interface from our EJB project.

    There is also a getFacade method which needs this simple type change as well:

    //private WidgetFacade getFacade() {
    private WidgetFacadeLocal getFacade() {
        return ejbFacade;
    }

  7. Delete the persistence.xml file generated within the Web project, since this will now be supplied with the EJB project.

  8. Modify the web.xml file and change the "version" attribute to be "2.5" to specify a valid version for WebLogic Server:

    <web-app version="2.5" ... >

  9. Using the "New ..." wizard, add a WebLogic Deployment descriptor to the Web project, and specify a shared library reference to the JSF 2.0 shared library that WebLogic Server supplies.

    <?xml version="1.0" encoding="UTF-8"?>
    <weblogic-web-app>
        <context-root>Widget</context-root>
        <library-ref>
            <library-name>jsf</library-name>
           <specification-version>2.0</specification-version>
           <implementation-version>1.0.0.0_2-0-2</implementation-version>
        </library-ref>   
    </weblogic-web-app>

    See the links for more details about JSF 2.0 and WebLogic Server, including instructions for how to deploy and reference the shared-library:

    http://buttso.blogspot.com/2010/05/jsf-20-support-in-weblogic-server-1033.html
    http://buttso.blogspot.com/2011/03/jsf-with-managed-beans-and-dependency.html

  10. Build the final application into an EAR file that is ready for deployment.

    Deploying the Application to WebLogic Server
    1. To deploy a JSF 2.0 application to WebLogic Server, the JSF 2.0 shared-library must be deployed.  See links referenced above for details on how to do this.

      http://buttso.blogspot.com/2010/05/jsf-20-support-in-weblogic-server-1033.html
      http://buttso.blogspot.com/2011/03/jsf-with-managed-beans-and-dependency.html

    2. To use JPA 2.0 with WebLogic Server, two optional libraries within the WebLogic Server installation must be placed into the classpath.  This can be automated through the use of a SmartUpdate patch, or it can be performed manually by setting a PRE_CLASSPATH environment variable and specifying the required libraries before starting the WebLogic Server domain. 

      $ export PRE_CLASSPATH=/Users/sbutton/Java/wls-1035-dev/modules/com.oracle.jpa2support_1.0.0.0_2-0.jar:/Users/sbutton/Java/wls-1035-dev/modules/javax.persistence_1.0.0.0_2-0-0.jar
      See the documentation for more details as needed:

      http://download.oracle.com/docs/cd/E17904_01/web.1111/e13720/using_toplink.htm#CIHDJHHI

    3. The application is also using the Bean Validation specification which is not supplied with WebLogic Server 10.3.4.  To ensure that the JSF 2.0 and JPA 2.0 implementation in TopLink can see the Bean Validation implementation and automatically enlist it's services, I added it as an additional library to the PRE_CLASSPATH environment variable:

      $ export PRE_CLASSPATH=${PRE_CLASSPATH):/Users/sbutton/Java/glassfish-31/glassfish3/glassfish/modules/bean-validator.jar

      Note here I am just referencing the library from a local GlassFish installation I have.  I could copy this library out into a separate location or even download it independently and reference it.  Call me lazy if you will ... :-)

    4. Start a WebLogic Server domain

    5. Using the WebLogic Console, configure the required datasource (jdbc/sample) to point at the Derby database and test to ensure it is working.

    6. Using the console, deploy the application.


    Test the application

    With the application deployed, it can be tested to observe the JSF 2.0, JPA 2.0 and Bean Validation uses working on WebLogic Server.

    For instance, create a new Widget and specify an incorrect email address.  You'll see that JSF will automatically detect the invalid value based on the @Pattern constraint set on the Widget entity, and display the accompanying message as an error message on the page.


    Correcting the email address value, the entry can be successfully be saved.



    Looking at the stdout on the console where the WLS domain was started, the use of JPA 2.0 via EclipseLink and the automatic enlistment of the Bean Validation implementation can be seen in the lines below:

    <May 16, 2011 3:58:26 PM CST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
    May 16, 2011 3:58:40 PM org.hibernate.validator.util.Version <clinit>
    INFO: Hibernate Validator 4.1.0.Final
    May 16, 2011 3:58:40 PM org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
    INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
    <May 16, 2011 3:58:40 PM CST> <Notice> <EclipseLink> <BEA-2005000> <2011-05-16 15:58:40.781--ServerSession(1625943009)--EclipseLink, version: Eclipse Persistence Services - 2.1.3.v20110304-r9073>
    <May 16, 2011 3:58:40 PM CST> <Notice> <EclipseLink> <BEA-2005000> <2011-05-16 15:58:40.782--ServerSession(1625943009)--Server: 10.3.5.0>
    <May 16, 2011 3:58:41 PM CST> <Notice> <EclipseLink> <BEA-2005000> <2011-05-16 15:58:41.266--ServerSession(1625943009)--file:/Users/sbutton/Projects/Domains/wls1035/servers/AdminServer/tmp/_WL_user/Widget/qb0nwv/Widget-EJB.jar_Widget-EJBPU login successful>

    If you forget to specify the JPA provider using the <provider> element in config.xml and deploy the application to a default WLS domain, then you may see the following error message when you try and access the application:


    This exception indicates that an application is using the JPA 2.0 API, but WebLogic Server can't find a JPA 2.0 provider.  This is the default condition of a WLS domain where the Kodo/Open JPA 1.0 provider is supplied at runtime.
     
    This can be easily modified as described above by specifying an explicit <provider> value for EclipseLink (or Hibernate if you are using that) or by altering the default JPA provider at the domain level using the WebLogic Console:



    Summary

    It proved to be quite straight forward to take the Java EE 6 CRUD application generated by NetBeans and alter it slightly to deploy and run successfully on WebLogic Server 10.3.4, using it's JSF 2.0 and JPA 2.0 support.

    11 May 2011

    Markus Quick Tests RichFaces 4.0 on WLS 10.3.4

    Nice to see this blog from Markus Eisele (belatedly on my part) in which he describes how to do a quick test of the RichFaces 4.0 showcase deployed on WLS 10.3.4 using it's optional support for JSF 2.0:

    http://blog.eisele.net/2011/04/running-richfaces-400final-showcase-on.html

    Thanks Markus, will try it out.