Search |
||
Getting started with HK2 - Part IIPosted by ss141213 on January 28, 2008 at 12:29 PM PST
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: Let's go through the contents, first our new module, hello-impl. Step 2: Choose the packages you want to export:
<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. Step 4:Decide the scope of components 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.
@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
@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 Q1. Why does HK2 use @Contract and @Service? Q2. What is Habitat in HK2? Conclusion »
Related Topics >>
Java Enterprise Comments
Comments are listed in date ascending order (oldest first)
Submitted by alegrn on Tue, 2008-01-29 14:26.
HK2 looks realy interesting. I would like to play with it. Unfortunatly I cann't build the example. Maven prints the following error message:
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Plugin could not be found - check that the goal name is correct: Unable to download the artifact from any repository
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=com.sun.enterprise -DartifactId=hk2-maven-plugin -Dversion=0.2-SNAPSHOT -Dpackaging=maven-plugin -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=com.sun.enterprise -DartifactId=hk2-maven-plugin -Dversion=0.2-SNAPSHOT -Dpackaging=maven-plugin -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
com.sun.enterprise:hk2-maven-plugin:maven-plugin:0.2-SNAPSHOT
from the specified remote repositories:
central (http://repo1.maven.org/maven2)
com.sun.enterprise:hk2-maven-plugin:maven-plugin:0.2-SNAPSHOT
from the specified remote repositories:
central (http://repo1.maven.org/maven2)
What can I do to get the example running?
Thank you.
PS: There seems to be something wrong with this posting-form. It clears it's input when pushing the preview button.
Submitted by ss141213 on Tue, 2008-01-29 21:42.
Hi alegrn,
Can you download the zip file again and try? I have updated the top level POM to include the extra Maven repositories from where HK2 related artifacts need to be downloaded. Since I had them set up in my ~/.m2/settings.xml, it was working for me. Sorry about that. Thanks. Look forward to your comments...
Sahoo
Submitted by ss141213 on Sun, 2008-04-06 11:53.
You can't inject into a plain Java class, because its construction is not controlled by anyone. However, if you want to use a Service from such a class, you can use the Habitat. Ask such questions in users@glassfish.dev.java.net.
Submitted by antsh on Sun, 2008-04-06 14:23.
Thank you for your quick response. I will send a letter to users@glassfish.dev.java.net.
Submitted by antsh on Sun, 2008-04-06 08:26.
Hi,
Thank you for this tutorial, I found it very useful.
My question:
How come only Services can inject other Servvices, why can we inject Services into a plain Java class?
For example my situation is like this:
I have a ConfigurationProviderService that gets all the parameters for the executable application on runtime and I need to use this service almost in every java class file, but I can't :( I always get a NullPointerException which means that Service was not initialized. Is there some way to use Services in plain java classes?
I added an extra java class to your example project, so that you can understand what I mean:
2nd-hello-world-hk2-sample\hello2-impl\src\main\java\sahoo\hello\implPlainClass.java
And uploaded the source to:
http://www.zone.ee/antsh/2nd-hello-world-hk2-sample.zip
Just try to execute the project.
Looking forward to your responce,
Anton
Submitted by sarahkho on Wed, 2008-09-17 06:44.
Hi Shahoo,
I tried very hard to run your samples with no luck, it looks like that something is wrong with the repositories, I included the output message and I would be grateful if you could take a look and let me know what is wrong.
Thanks
The error message:
============================================================
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'hk2'.
Downloading: http://download.java.net/maven/glassfish//com/sun/enterprise/hk2-parent/...
Downloading: http://download.java.net/maven/glassfish//com/sun/enterprise/hk2-parent/...
Downloading: http://download.java.net/maven/1//com.sun.enterprise/poms/hk2-parent-0.2...
Downloading: http://download.java.net/maven/2//com/sun/enterprise/hk2-parent/0.2-SNAP...
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error building POM (may not be this project's POM).
Project ID: null:hk2-maven-plugin:maven-plugin:0.2-SNAPSHOT
Reason: Cannot find parent: com.sun.enterprise:hk2-parent for project: null:hk2-maven-plugin:maven-plugin:0.2-SNAPSHOT for project null:hk2-maven-plugin:maven-plugin:0.2-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Wed Sep 17 18:11:31 IRDT 2008
[INFO] Final Memory: 1M/4M
[INFO] ------------------------------------------------------------------------
============================================================
Submitted by ss141213 on Wed, 2008-09-17 07:32.
I have updated the sample zip that now uses latest non-SNAPSHOT version of HK2. So, you won't face such build issues any more.
Submitted by andreijuan on Thu, 2009-01-15 17:10.
Thanks a lot for the tutorial, it makes very clear important aspects of module startup. One thing that puzzles me though is that when I run "mvn hk2:run", the start() of my module gets called, and then... that's it, the application just exits (without even calling the stop() of my module). This makes it very easy to create a "hello world" application, but what about an application that actually *does* something?
I could, for example, include all the code of my application (including all interaction with other modules, threading etc.) in my module's start() -- which for some reason seems to have replaced run() at some point -- but is that normal? I mean, should my module just "keep starting"? Or should I do some other magic that I'm not aware of in order to convince HK2 to call some sort of "run()" after initializing my module(s)?
Thanks again!
Submitted by starinsky on Fri, 2009-02-20 01:28.
Yes, your blogs are quite helpful. I have read your several blogs.It seems to me that you could predict what we may have problem in understanding the technology. So you tell us "why" before we ask you. Of course, the truth is you are quite a kind-hearted man. You want to dedicate your knowledge. So I want to thank you sincerely.
|
||
|
|