The Source for Java Technology Collaboration
User: Password:



Sahoo's Blog

Community: Java Enterprise Archives


Updated instructions to use OpenJPA in GlassFish

Posted by ss141213 on May 12, 2008 at 11:23 AM | Permalink | Comments (0)

Layout of OpenJPA installation has changed since I last blogged about using OpenJPA in GlassFish. Let's say one installs OpenJPA in a directory called ${OPENJPA_HOME}. Earlier (I am talking about the days when OpenJPA was still in Apache incubator), all the jars would live under ${OPENJPA_HOME}/lib directory. Now, things have changed. The primary artifact, openjpa-${version}.jar, which contains classes built out of OpenJPA codebase lives under ${OPENJPA_HOME}; where as all the other library jars live under ${OPENJPA_HOME}/lib. So, all you need to do is to copy the appropriate jars like this:

 cp ${OPENJPA_HOME}/openjpa*.jar ${OPENJPA_HOME}/lib/*.jar ${GLASSFISH_HOME}/domains/domain1/lib 

and restart GlassFish. For further information, please refer to my earlier blog. I have updated that blog as well.

For issues, please don't hesitate to contact us at users (at) glassfish.dev.java.net



Bug in Bundle.getResource() in Knopflerfish?

Posted by ss141213 on May 01, 2008 at 12:38 AM | Permalink | Comments (4)

I was running a simple test on multiple OSGi platforms. I am seeing some difference in behavior when I run it on Knopflerfish #2.0.3. Upon investigation, I observed that Bundle.getResource() implementation on Knopflerfish does not use the parent class loader of the bundle even when I set org.osgi.framework.bootdelegation=*.

Here is a simple code that I used to test my theory:

public class Activator implements BundleActivator{

public void start(BundleContext context) throws Exception {
Class libClazz = context.getBundle().loadClass("sahoo.Library");
System.out.println("libClazz = " + libClazz);
URL libRes = context.getBundle().getResource("sahoo/Library.class");
System.out.println("libRes = " + libRes);
}
...

The above code prints non-null value for libClazz, but a null value for libResource. If Bundle.loadClass("sahoo.Library") could load the class, how could Bundle.getResource("sahoo/Library.class") return null? It works as expected in other OSGi implementations.

To ensure that sahoo.Library.class is available in the parent class loader, I wrote a Main class which creates a ClassLoader that has both the knopflerfish framework.jar and my library.jar in search path. I then use that classloader to launch knopflerfish.

Has anyone else faced similar issues? I think this is a serious bug in knopflerfish. I tried to get a confirmation by reporting it in their forum, but no luck. I also tried using the dev forum, but no difference. Is there a better way to ask them questions? I don't know. So I thought I would document what I observed.



GlassFish V3 on OSGi - Part I

Posted by ss141213 on April 15, 2008 at 07:56 PM | Permalink | Comments (0)

I guess by now you have heard the big news coming out of GlassFish community. We have put back initial code that enables GlassFish to run on an *OSGi* R4 platform. Felix is currently our default OSGi runtime. I am assuming you have either read Jerome's blog or Eduardo's posting in The Aquarium. If you have not, I suggest you read them first. Jerome and Eduardo have explained some of the rational behind this change and what to expect in coming days. Now some details not covered there:

The following picture tries to give an idea as to how the runtime looks like when GlassFish is running on an OSGi platform:

GFOnOSGiDiagram.png

All our GlassFish modules including the Java EE APIs are packaged as OSGi bundles. Some of you may wonder what's HK2's role here. HK2 has following layers, viz:
module layer - responsible for class loading and life cycle management
component layer - which is responsible for component registration, injection, outjection, etc.
config layer - responsible for configuring components by reading data from XML file. The XML file can be transactionally updated to reflect changes in component.
A simple class diagram that shows some of the HK2 abstractions (except those of config layer) is shown below:
HK2Model.jpg

We have implemented HK2' module layer APIs on OSGi by delegating to OSGi module layer. HK2's component layer and config layer relies on HK2's module APIs. Once those APIs are available, it is not that difficult to make those two layers available as OSGi bundles. Except for cases like URLStreamHandler registration, GlassFish modules do not use OSGi APIs directly; they use HK2 module APIs which are available on both the runtimes. That allows them to run unchanged on both the runtimes. Some other day, I shall talk about the service mapper.

Last, but not the least, I want to thank Felix community for the excellent support that they provide in their forum. It's not just the framework that I found easy to use. Their maven-bundle-plugin, which wraps Peter Krien's bnd tool, makes life of maven users so much easier.

Now, before you ask me, let me preempt you:

Why did we take this approach?
A lot of GlassFish code was already written, so we wanted an easier migration path without disrupting our schedule.

What are the benefits of this approach?
Well, it allows us to experiment on both the modes. Theoretically, given another compatible module system, we can switch to using that with relative ease.

What are the drawbacks of this approach?
By limiting ourselves to HK2 APIs, we are not able to take advantage of rich module management APIs that OSGi provides.

Will we continue to support both the modes?
Not very long. But, that does not mean that HK2 will vanish. As Jerome explains in his blog, HK2 will continue to provide component layer and config layer.

How does GlassFish use bundle repository?
That is something I have to investigate next.

What other OSGi implementation does it run on?
Theoretically speaking, since our code is written against R4 spec, it should run in any compliant implementation - it's a matter of configuration I would say. We have tried all major three and it works. More on this to follow in time to come. Felix is currently our default platform - it is distributed as part of our runtime.

What's next?
This is just the beginning. We have so many things lined up in this area. I have a long TODO list which I have to prioritize. We hope you shall provide constructive feedback to make it better. As Eduardo mentioned in his blog, please wait for the builds to stabilize.



Getting started with HK2 - Part II

Posted by ss141213 on January 28, 2008 at 12:29 PM | Permalink | Comments (5)

Download The Sample

This is a sequel to my last blog where I described a Hello World sample running on HK2. As promised there, I am going to expand that sample to show module management, class loading, component injection, instantiation cascading features of HK2 working.

Structure of the sample


hello-world-hk2-sample2/
/pom.xml
/hello2-startup/pom.xml
/src/main/java/sahoo/hello/startup/MyStartup.java
/hello2-impl/pom.xml
/src/main/java/sahoo/hello/api/Foo.java
/src/main/java/sahoo/hello/api/Bar.java
/src/main/java/sahoo/hello/impl/FooImpl.java
/src/main/java/sahoo/hello/impl/BarImpl.java

The modules are organized the same way as our earlier example except that I have added a new module called hello2-impl. The new module holds some implementation details. It is introduced to show how inter-module dependency is managed by HK2.

Instructions to build and run remain unchanged. You can run mvn -f hello-world-hk2-sample-2/pom.xml install to build the sample. To run it, do one of the following:
mvn -f hello-world-hk2-sample-2/hello2-startup/pom.xml hk2:run
or
hello-world-hk2-sample-2/run.sh
Refer to the earlier blog for an explanation of the above steps.

Let's go through the contents, first our new module, hello-impl.
Step 1. Make it a HK2 module:
To do this, we need to specify packaging type as hk2-jar in its pom.xml. Since this is a custom packaging type, we need to configure the pom.xml with the plugin, hk2-maven-plugin, which provides such support. Since this plugin as well as HK2 modules are not available in standard Maven repo, you have to configure some extra repositories in the parent POM (you can do it in your ~/.m2/settings.xml as well, if you want to avoid doing it every time).

Step 2: Choose the packages you want to export:
Next, let's see how to choose the packages we want to export. By default, HK2 module management exports all packages from a module to other modules. This is just opposite to how OSGi behaves. hello2-impl module has two packages, viz: sahoo.hello.api and sahoo.hello.impl. The former one contains interfaces that we would like to export, where as the latter one contains implementation details that we would like to hide from others. Currently, there is no package level annotations defined in HK2 to mark some packages for exporting, hence we have to manually configure our hk2-maven-plugin in pom.xml to generate the following manifest entry:
HK2-Export-Package: sahoo.hello.api
It is achieved by configuring the hk2-maven-plugin in pom.xml as follows:


<build>
<plugins>
<plugin>
<groupId>com.sun.enterprise</groupId>
<artifactId>hk2-maven-plugin</artifactId>

<version>...</version>
<extensions>true</extensions>
<configuration>
<archive>
<manifestEntries>
<HK2-Export-Package>
sahoo.hello.api
</HK2-Export-Package>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

The above syntax is same as what is applicable to maven-jar-plugin.

Step 3: Define contract classes Foo.java and Bar.java

In HK2, a contract is a Java interface which is annotated with @Contract. Typically a service or a component has two parts, viz: an interface class which defines the public interface of the service and an implementation class. HK2 allows you to develop a contract-less component as well. In HK2, the interface is annotated with @Contract, where as the implementation is annotated with @Service.
If you don't know why HK2 requires you to use @Contract, don't worry, it will be cleared in due course of time.
In our case, both Foo.java
Foo.java and Bar.java have such annotations in place. Keeping the true spirit of modularisation, we have defined Foo and Bar in sahoo.hello.api package, which is the package that is being exported by hello-impl module. The implementations are hidden from other modules.

Step 4:Decide the scope of components
There is something called scope attribute in @Contract. The default value for scope is Singleton.class. As the name suggests, when you ask the component manager for a component, it uses this information to decide whether to create a new instance or return an existing instance. If it decides to return an existing instance, the scope can further control where it searches for an existing instance. Singleton, as the name suggests, implies that there will be no more than one such instance of this contract type. There is another scope defined in HK2 called PerLookup.class which means every time you ask for such a component, a new instance is created by HK2 component manager as if you called the constructor. A very powerful feature of HK2 is the notion of user defined scope. I have a sample ready that shows how to use your own scope, but let me defer discussion on that to another day.
In our case, we are relying on the default scope.

Step 5:Define component classes FooImpl.java and BarImpl.java

They are both defined in a package called sahoo.hello.impl, which is not exported by our module. Now let's take a closer look at our component classes.
A component class must be annotated with @Service.
A component class must have public, no-arg constructor.
A component can depend on other components. To express such dependency, a component can use @Inject annotation. While specifying @Inject, one should specify the contract interface type in order to avoid tight coupling with any given implementation if possible. Our component Foo.java follows all these rules as shown below:


@Service
public class FooImpl implements Foo {
@Inject Bar bar;

public FooImpl() {
System.out.println("FooImpl() called");
}

public void doit() { bar.doit();}
}

A natural question is when does the injected field bar get initialized? It is initialized by HK2 framework after the constructor call, which means you should not be accessing this field in your default constructor. If you need to specify some business logic as part of construction, then make your component implement PostConstruct interface.

Step 6: Write a startup module
So far, we have described about hello-impl module which defines two contracts called Foo and Bar, but how does HK2 know about it? Who uses them? That's where our startup module comes into picture. Remember, in my previous blog, I told this is the primordial module? This is the module that consumes those contracts. Now let's look at the only class that is defined in this module:


@Service
public class MyStartup implements ModuleStartup
{
@Inject Habitat habitat;
@Inject Foo foo;

public void setStartupContext(StartupContext context) {
}

public void run() {
System.out.println("Hello World - My first HK2 Sample");
System.out.println("Injected foo = " + foo);
Foo lookedUpFoo = habitat.getComponent(Foo.class, null);
System.out.println("habitat.getByComponent(Foo.class, null) = " +
lookedUpFoo);
// Since Foo is Singleton scoped, the following assertion holds good
assert(foo == lookedUpFoo);
foo.doit();
}

}

It is itself a component, for it is annotated with @Service. What contract does it have? It's ModuleStartup. Since it is a component, it can use dependency injection. See how it is injected with a Foo object and a Habitat object. What is this Habitat object? Well, Habitat is the component manager in HK2.

Since, hello-startup module uses interfaces from hello-impl module, we have to set appropriate dependency in hello-startup's pom.xml. When we do this, out hk2-maven-plugin is smart enough to generate the following manifest headers in hello-startup's META-INF/MANIFEST.MF:

HK2-Import-Bundles: sahoo:hello2-impl, com.sun.enterprise:hk2

That's it. You are all set to build and run the sample.

Observations
You can see HK2 automatically starting hello2-impl module when it tries to start the primordial module. You can also see instantiation cascading: MyStartup -> Foo -> Bar because of Bar injected in Foo injected in MyStartup. Similarly, you can see Singleton scope in action. Next time, when the code asks for Foo type component to the component manager, it is returned the previous instance. To test package hiding, change the class to load FooImpl.class directly from MyStartup, and you will get a ClassNotFoundException.

Q1. Why does HK2 use @Contract and @Service?
It's an ease of development thing. Even Java SE platform provides a service framework, but that does not require any annotations, but why HK2 requires? Java SE requires programmers to generate META-INF/services file as described here, where as HK2 generates the appropriate meta-information by parsing the annotations at compile time. This is done by HK2 supplied hk2:compile goal.

Q2. What is Habitat in HK2?
This is the component manager in HK2. Think like JNDI Naming Manager in Java EE. Well, it's much more than that actually. More discussion on Habitat some other day. Got to sign off for the day.

Conclusion
I hope you found this useful. As usual, your comments are useful. Stay tuned for more on and .



Getting started with HK2 - Part I

Posted by ss141213 on January 28, 2008 at 06:30 AM | Permalink | Comments (5)

Download The Sample

Now that I am working in HK2, I shall share my experiences of HK2 with others via my blogs. I firmly believe that examples are a great way to learn a new technology. So, I will start with a "Hello World" type application. The fact that you are reading this blog makes me think that you already know what HK2 is. Although HK2 is being used in development of ultra light-weight, modular, next generation GlassFish application server, any Java SE programmer can use it to write modular applications. It has a very nice component model with IoC support. In fact, this sample has nothing to do with server side programing. The complete sample along with Maven build scripts, etc. can be downloaded from here.

Structure of the sample


hello-world-hk2-sample/
/pom.xml
/hello-startup/pom.xml
/src/main/java/sahoo/hello/startup/MyStartup.java

As you notice, even though there is only one module, named hello-startup, I have decided to keep a top level pom.xml with packaging type pom and kept hello-startup module in a sub-project. I have done so because I know, in reality, one has multiple modules, so why not get used to that kind of structure from beginning?

Prerequisite:
1. Maven 2
2. Java SE 6 or above.
You can use Java SE 5, but you need to get hold of a StAX implementation and put it in classpath, for HK2 needs StAX at runtime.

How to build
mvn -f hello-world-hk2-sample/pom.xml install

(-f option to mvn instructs it to use a specified pom.xml. It is equivalent to cd to hello-world-hk2-sample and invoking 'mvn install')

How to run
There are a couple of options:
1. Using maven:
HK2 provides a plugin goal (hk2:run) which I find very handy to use. This goal must be invoked using the statup module's pom. So, you can invoke it like this:

mvn -f hello-world-hk2-sample/hello-startup/pom.xml hk2:run

2. Running a start up script:

./hello-world-hk2-sample/run.sh

run.sh is a very simple script that copies all the necessary HK2 jar files from your Maven local repository to a directory called ./lib. It also copies your application jar files to ./lib. Then it launches HK2 using the following command:

java -jar ./lib/hk2-0.2-SNAPSHOT.jar

Note: There are a couple of variables like JAVA_HOME and MAVEN_REPO_LOCAL in run.sh that you need to configure for your environment.

Sample Description:
Let's now take a look at our program.
1. First the pom.xml:
A. The packaging type is hk2-jar. Who provides this packaging support? HK2 provides a plugin called hk2-maven-plugin which provides this packaging support. It helps generating necessary manifest headers in our module jar. Since maven does not know about this plugin, we configure it in our build section.
B. We also specify dependency on HK2 module in the dependency section so that we can use HK2 APIs in our program. Please note that I specify the HK2 version as a property which is set in the parent pom.xml. This allows me to control it in one place only. Rest of the pom.xml needs no explanation.

2. Let's now take a look at our only class, MyStartup.java.
It is annotated as @Service and implements ModuleStartup. Both are needed because hello-startup is the primordial module - the first user supplied module to be started by HK2. When HK2 starts, it searches all the modules for a class that meets the above criteria. If it finds only one such class, then it considers the module containing the class as the main bundle. It then instantiates the class and calls the setStartupContext(). It then calls the run() method of the ModuleStartup interface. Our System.out.println code is part of the run().

Conclusion
I know this sample does not show how HK2 manages module dependency, class loading, component injection, etc. Stay tuned, more blogs about coming soon... As usual, comments are most welcome.

Useful Links:
How to develop module in HK2
More blogs about



Introduction to using Java Persistence API in a web application in Java EE environment

Posted by ss141213 on December 04, 2005 at 03:29 PM | Permalink | Comments (27)

The Java Persistence API is the standard API for the management of persistence and object/relational mapping in Java EE 5 platform. Every Java EE 5 compatible application server will support this API. In this entry I will show how to use this API from a web application in Java EE environment.
Since the public review version of Java Persistence API specification, there have been a number of significant changes about packaging of applications that use Java Persistence API. So I will also show how to package such an application in a portable way. In this exercise, I will not use any kind of IDE because I don't want any magic! This article is going to be a long one because I am trying to explain the steps in detail as well as why certain things are done the way they are. But the steps are very simple as you can see from the README.

What is the example?
It's a web application which has a login page and a new user registration page. It talks to a database where user details are stored. The complete sample is available here. There is a README inside that zip file as well.

Requirements
The Reference Implementation(RI) of the Java Persistence API is being done in glassfish project. You can download the latest promoted build and try out the sample yourself.
Although I am using the RI to build and run this sample, atmost you have to do some very minor changes to persistence.xml and build.xml to make this app build and run in any other application server that supports Java EE 5 specification.

Detailed Steps

Step #1: Write entity bean UserCredential.java

Points to note about this entity bean are:
1) This is a Plain Old Java Object (POJO): It does not extend any predefined class, nor does it implement any particular interface other than java.io.Serializable. An entity bean must implement java.io.Serializable interface if it is used in RMI-IIOP interface. Since in this example, RMI-IIOP is not used, technically this bean does not have to implement this interface. Never-the-less it is a good idea to make an entity bean RMI-IIOP ready, so I have done so.

2) There is no deployment descriptor needed to specify that it is an entity bean. Instead the class has been annotated as @Entity as shown below:

@Entity
public class UserCredential implements java.io.Serializable
.

The persistence provider automatically determines whether we are annotating FIELDs or PROPERTIEs. In this case, we have decided to annotate fields.

3) Every entity bean must have an identity. In our case, it is specified using @Id as below:

@Id private String name;

I have chosen to use @Id because we have a single field primary key. Other annotations like @IdClass, @EmbeddedId are typcally used for composite primary key.

4) Also note that we have not used @GeneratedValue along with @Id. When an id field is not annotated with @GeneratedValue, it means that user is responsible for setting the identity. Provider will not set the id field.

5) Although it is possible to specify exact table name and column names for the entity bean, we can rely on the default mapping that the specification defines. Because of the default mapping rules, UserCredential bean gets mapped to a table called USERCREDENTIAL, name & password fiels get mapped to NAME and PASSWORD columns respectively.

Step #2: Define a persistence unit

A Persistence Unit (PU) is a logical grouping of a set of related entity beans. A PU also contains configuration details about the entity managers that are going to manage these entity beans. Actually the ocnfiguration is applied to an EntityManagerFactory which in turn creates homogenious entity manager instances. To define a PU we need to write a node in persistence.xml file. Points to note about this persistence.xml are:

1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name em1.

2) We need not specify any other elements/attributes, as the default values are just fine for most applications. e.g. by default the entity manager's transaction type is JTA.

3) There is no need to enumerate all the entity bean class names inside because we are defining only one PU in this persistence.xml and we will be packaging the entity classes along with this persistence.xml in a jar file, so container can discover all the entity beans.

Step #3: Write LoginServlet.java

Points to note about this servlet are:
1) It talks to database using EntityManager API. It declares dependency on an EntityManagerFactory using @PersistenceUnit annotation:

@PersistenceUnit private EntityManagerFactory emf;

Since there is only one Persistence Unit(PU) defined in the scope of the web-app, there is no need to specify the unitName in @PersistenceUnit. Please also note that an injected variable in a servlet or ejb must not be declared static or final. In our example, emf follows this rule as well.

2) Also note that the servlet does not have an instance field of type EntityManager. This is because EntityManager is not thread safe. Since this servlet is not denoted as a SingleThreadModel servlet, one instance of servlet gets shared by mutiple clients and service method of servlet can be called by multiple threads concurrently. So we can't directly inject an EntityManager. Instead we inject an EntityManagerFactory which is thread safe.

3) In the service(), we create an EntityManager using the following code:

EntityManager em = emf.createEntityManager();

We also close the EntityManager in the finally block.

4) When user tries to login using a user name and password, it uses

UserCredential credential = em.find(UserCredential.class, name);

to find a matching UserCredential entity in the database.

5) Since EntityManager.find does not require a transaction to be started, the servlet does not have to begin a transaction before calling em.find().

Step #4: Write RegistrationServlet.java

Note:
1) It uses an injected EntityManagerFactory.

2) It uses

EntityManager.persist()

to create a new entity in the in the database .

3) Since EntityManager.persist() needs to be called in the context of a transaction, this servlet begins a transaction by calling

utx.begin()

and commits the tx before returning.

4) Also note that it uses an injected UserTransaction object as follows:

@Resource private UserTransaction utx;

Unlike EntityManager, UserTransaction is thread safe, so it is OK to inject it into a servlet.

5) Also see how we ensure that when we close the EntityManager there is no active transaction context, otherwise EntityManager.close() will throw an exception.

Step #5: Write web.xml

We are having to write an web.xml only because we have to define a couple of request path mappings to servlets.

Step #6: Write a couple of html files
Refer to login.html and registration.html inside the sample zip file. They are used to call the servlets.

Step #7: Build using build.xml

This is a very simple build.xml just to demonstrate the compilation and packaging process.
The build targets are:
build -- This builds the war file.
clean -- cleans
verify -- verify uses a tool called verifier that checks compliance of the application against Java EE spec.
deploy -- deploys the war file
undeploy -- undeploys the war file
The last three targets are specific to Java EE 5 Reference Implementation (a.k.a. Sun Java System Application Server 9 PE).

As you can see, to compile only library needed is javaee.jar which contains the Java EE 5 platform APIs.
Packaging is done in two steps:

a) build-entities target which compiles only entity beans, copies persistence.xml to output directory and make a jar file called entities.jar. See entities.jar contains persistence.xml in META-INF dir. This jar file is used during compilation of servlets. More over this is also bundled inside the war file's WEB-INF/lib directory.

b) build-web-app1 target which compiles the servlets, copies web.xml and html files to output directories amd makes a war file called web-app1.war. A few points worth noting here are:
in addition to javaee.jar, entities.jar is also used while compiling the servlets.
servlet classes are bundled in WEB-INF/classes directory.
entities.jar is bundled inside WEB-INF/lib directory

Another packaging option is to package META-INF/persistence.xml and entity classes in WEB-INF/classes. But I just feel having a separate jar file with entities in it keeps things clean. It improves reusability.

Step #8: Set up a data source

By default entity manager uses the default pre-configured data source with JNDI name jdbc/__default that glassfish comes with. This data source talks to a Derby database called sun-appserv-samples. Refer to the README where I have listed the command needed to create the tables in Derby. Glassfish has a feature called Java2DB which can autocreate the database schema during deployment, but because of a bug this feature is not currently supported for Derby. Very soon (in a week or so), this bug is going to be fixed. Watch out glassfish EJB 3.0 persistence project page.

Step #9: Run the web-app
Type http://localhost:8080/web-app1/login.html in the browser. Replace localhost & 8080 by host and port as appropriate in your env.

Hope this entry is useful. In the next entry, we will take a step further and write an enterprise application where a web application talks to database using session beans.

Technorati Tags:





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds