Sunday 25 November 2012

Worldclock on Jigsaw and HK2

In the previous post I 'ported' HK2 to work on Jigsaw, in this post I adapt Worldclock to use it.

Retrieving the existing code:

svn checkout https://svn.java.net/svn/worldclock-application~svn/tags/application6-jigsaw-maven ~/dev/worldclock-hk2

And the new pom and module-info:

svn checkout https://svn.kenai.com/svn/lh-playground~svn/jigsaw/worldclock-hk2 ~/dev/worldclock-hk2-downloads

Panel

Overwrite the existing pom and module info for the panel:
cp ~/dev/worldclock-hk2-downloads/panel/pom.xml ~/dev/worldclock-hk2/panel/
(update the libraryDirectory path for your set up / username, gedit  ~/dev/worldclock-hk2/panel/pom.xml & )
cp  ~/dev/worldclock-hk2-downloads/panel/src/main/java/lh.worldclock.panel/module-info.java ~/dev/worldclock-hk2/panel/src/main/java/lh.worldclock.panel/
Add the sample HK2 dependency injection contract:
mkdir -p ~/dev/worldclock-hk2/panel/src/main/java/lh.worldclock.panel/lh/worldclock/hk2/
gedit ~/dev/worldclock-hk2/panel/src/main/java/lh.worldclock.panel/lh/worldclock/hk2/PanelProvider.java &
then add the content
package lh.worldclock.hk2;

import lh.worldclock.core.WorldClockBoard;
import org.jvnet.hk2.annotations.Contract;

@Contract
public interface PanelProvider
{
  WorldClockBoard getPanel();
}

Add the sample HK2 dependency injection service:
gedit ~/dev/worldclock-hk2/panel/src/main/java/lh.worldclock.panel/lh/worldclock/hk2/PanelProviderImpl.java &
then add the content
package lh.worldclock.hk2;

import lh.worldclock.core.WorldClockBoard;
import org.jvnet.hk2.annotations.Service;

@Service
public class PanelProviderImpl implements PanelProvider
{
  @Override
  public WorldClockBoard getPanel()
  {
    return new WorldClockBoard();
  }
}
build
cd ~/dev/worldclock-hk2/panel/
mvn -Dmaven.test.skip=true clean install
(if the build fail due to  invalid characters, edit the file and remove the comments
gedit ~/dev/worldclock-hk2/panel/src/main/java/lh.worldclock.panel/lh/worldclock/core/WorldClockBoard.java & )


Application


Overwrite the existing pom and module info for the application:
cp ~/dev/worldclock-hk2-downloads/application/pom.xml ~/dev/worldclock-hk2/application/
(update the libraryDirectory path for your set up / username, gedit  ~/dev/worldclock-hk2/application/pom.xml & )
cp  ~/dev/worldclock-hk2-downloads/application/src/main/java/lh.worldclock.application/module-info.java ~/dev/worldclock-hk2/application/src/main/java/lh.worlclock.application/

Adjust WorldClockPanel:
gedit ~/dev/worldclock-hk2/application/src/main/java/lh.worlclock.application/lh/worldclock/WorldClockPanel.java &

replace constructor start with:
   public WorldClockPanel(final WorldClockBoard board)
  {
//    board = new WorldClockBoard();
    this.board = board;
Adjust WorldClockFrame:
gedit ~/dev/worldclock-hk2/application/src/main/java/lh.worlclock.application/lh/worldclock/WorldClockFrame.java &

add import
 import lh.worldclock.core.WorldClockBoard;

remove the initialisation of pane
 WorldClockPanel pane;

replace constructor start with:
   public WorldClockFrame(ImageIcon icon, final WorldClockBoard board)
  {
    pane = new WorldClockPanel(board);
Adjust WorldClock
gedit ~/dev/worldclock-hk2/application/src/main/java/lh.worlclock.application/lh/worldclock/WorldClock.java &

add imports
import com.sun.enterprise.module.bootstrap.ModuleStartup;
import com.sun.enterprise.module.bootstrap.StartupContext;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.annotations.Service;
import lh.worldclock.core.WorldClockBoard;

replace class declaration
    @Service
    public class WorldClock implements ModuleStartup

make the frame non static
/*static*/ WorldClockFrame frame = null;
 add the injection
   @Inject
  WorldClockBoard board;
make main method non static

make void showWindow() non static and change
frame = new WorldClockFrame(icon, board);

to add the board

make   private PopupMenu createPopup() non static

add the following new methods
  public void setStartupContext(StartupContext context)
  {
  }

  public void start()

  {
    main(new String[]{});
  }

  public void stop()
  {
  }
build
cd ~/dev/worldclock-hk2/application/
mvn -Dmaven.test.skip=true clean install

Time to run:
cd ~/dev/hk2-jigsaw/jigsaw-adapter/
mvn lh.jigsaw:jigsaw-maven-plugin:run

HK2 and Jigsaw


In 2007, Jerôme Dochez presented HK2 as a module system loosely based on JSR277, I tend to see Jigsaw as the continuation of JSR277, so I wanted to see how HK2 could interface with Jigsaw.

Setting up the environement:

1. Build Jigsaw
2. Build the Maven plugin for Jigsaw
3. Download and extract Maven 3 in ~/dev
4. Export the variables:
export M2_HOME=~/dev/apache-maven-3.0.4/
export MAVEN_HOME=~/dev/apache-maven-3.0.4/
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-i386'
export PATH=$JAVA_HOME/bin:$M2_HOME/bin:$PATH
give some extra room to Maven:
export MAVEN_OPTS="-XX:PermSize=64M -XX:MaxPermSize=128M"

Get and build HK2:

svn checkout https://svn.java.net/svn/hk2~svn/tags/hk2-parent-1.6.32 ~/dev/hk2-1.6.32
cd ~/dev/hk2-1.6.32
mvn -DskipTests=true -Prelease-phase1 clean install
mvn -DskipTests=true clean install

Get the additions/replacements:

In order to reduce the amount of typing/copying some of the added/modified files are downloadable.
svn checkout https://svn.kenai.com/svn/lh-playground~svn/jigsaw/hk2 ~/dev/hk2-jigsaw-downloads

Patch HK2:

HK2 1.6.32 still uses the APT to build, this is removed from Java8/Jigsaw, so some adjustments are needed. These replace APT API with JSR269 API.
cd ~/dev/hk2-1.6.32/
patch -p0 < ~/dev/hk2-jigsaw-downloads/hk2-1.6.32-java7-maven-plugin.diff
as a result of the patch some of the tests in HK2 are failing, so disabling them for now
gedit ~/dev/hk2-1.6.32/pom.xml &
then comment line  307 (<module>auto-depends-tests</module>).
Build the patched version:
mvn -DskipTests=true clean install

Clean up no longer needed classes from the Maven plugin:

rm -f ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/CompositeAnnotationProcessorFactory.java
rm -f ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/AptInvoker.java
rm -f ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/AptCompiler.java

Adjust hk2-maven-plugin for Jigsaw:

Replace components.xml with a version that defines the packaging type to hk2-jmod rather than hk2-jar, and that also adds the Jigsaw extensions.
 cp ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/hk2-maven-plugin/src/main/resources/META-INF/plexus/components.xml ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/resources/META-INF/plexus/components.xml
Adjust  PackageMojo:
gedit ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/PackageMojo.java &
replace line 109:
@parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
with
@component role="org.codehaus.plexus.archiver.Archiver" roleHint="jar"

Adjust RunMojo:
gedit ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/RunMojo.java &

set the goal to hk2-run on line 65 so that the default run is the Jigsaw run

Add the non compile parts from the Jigsaw Maven plugin and override the compile part:
cp -r ~/dev/jigsaw-maven-plugin/src/main/java/lh ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/
mv  ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/lh/jigsaw/plugin/AbstractCompilerMojo.java ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/
mv  ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/lh/jigsaw/plugin/CompilerMojo.java ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/
Adjust  AbstractCompilerMojo:
gedit  ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/AbstractCompilerMojo.java &

replace the package
package lh.jigsaw.plugin;
with
package com.sun.enterprise.module.maven;


Adjust CompilerMojo:
gedit  ~/dev/hk2-1.6.32/hk2-maven-plugin/src/main/java/com/sun/enterprise/module/maven/CompilerMojo.java &

replace the package
package lh.jigsaw.plugin;
with
package com.sun.enterprise.module.maven;

Adjust the pom:
gedit ~/dev/hk2-1.6.32/hk2-maven-plugin/pom.xml &
Add to the build:
         <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
                <dependencies>
                   <dependency>
                     <groupId>org.codehaus.plexus</groupId>
                     <artifactId>plexus-compiler-javac</artifactId>
                     <version>1.8.1-jigsaw</version>
                     <exclusions>
                        <exclusion>
                          <groupId>org.codehaus.plexus</groupId>
                          <artifactId>plexus-component-api</artifactId>
                        </exclusion>
                     </exclusions>
                  </dependency>
                </dependencies>
            </plugin>
        </plugins>
Replace the auto-depends-plugin dependency with:
         <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>auto-depends-plugin</artifactId>
            <version>${project.version}</version>
            <exclusions>
              <exclusion>
                <groupId>com.sun</groupId>
                <artifactId>tools</artifactId>
              </exclusion>
            </exclusions>
        </dependency>
Replace the plexus-compiler-javac dependency with:
     <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-compiler-javac</artifactId>
      <version>1.8.1-jigsaw</version>
      <exclusions>
        <exclusion>
          <groupId>org.codehaus.plexus</groupId>
          <artifactId>plexus-component-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
Build the modified plugin with Jigsaw:
export JAVA_HOME=~/dev/jigsaw/build/linux-i586/jdk-module-image
cd ~/dev/hk2-1.6.32/hk2-maven-plugin/
mvn clean install

Make (parts of) hk2 Jigsaw friendly (ie Jigsaw projects):


JSR330 support
mkdir ~/dev/hk2-jigsaw
cp -r ~/dev/hk2-jigsaw-downloads/hk2-jigsaw/hk2jsr330/ ~/dev/hk2-jigsaw/
cd ~/dev/hk2-jigsaw/hk2jsr330/
mvn -Dmaven.test.skip=true clean install
(update the libraryDirectory path for your set up / username, gedit ~/dev/hk2-jigsaw/hk2jsr330/pom.xml & )
 
HK2-API
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/hk2-api/pom.xml ~/dev/hk2-1.6.32/hk2-api/
(update the libraryDirectory path for your set up / username, gedit  ~/dev/hk2-1.6.32/hk2-api/pom.xml & )

mkdir ~/dev/hk2-1.6.32/hk2-api/src/main/java/lh.jigsaw.hk2.api
mv  ~/dev/hk2-1.6.32/hk2-api/src/main/java/org/  ~/dev/hk2-1.6.32/hk2-api/src/main/java/lh.jigsaw.hk2.api/
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/hk2-api/src/main/java/lh.jigsaw.hk2.api/module-info.java ~/dev/hk2-1.6.32/hk2-api/src/main/java/lh.jigsaw.hk2.api/
build
cd ~/dev/hk2-1.6.32/hk2-api/
mvn -Dmaven.test.skip=true clean install

Auto-depends
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/auto-depends/pom.xml ~/dev/hk2-1.6.32/auto-depends/
(update the libraryDirectory path for your set up / username, gedit  ~/dev/hk2-1.6.32/auto-depends/pom.xml & )
mkdir ~/dev/hk2-1.6.32/auto-depends/src/main/java/lh.jigsaw.hk2.autodepends
mv ~/dev/hk2-1.6.32/auto-depends/src/main/java/org/ ~/dev/hk2-1.6.32/auto-depends/src/main/java/lh.jigsaw.hk2.autodepends
mv ~/dev/hk2-1.6.32/auto-depends/src/main/java/com/ ~/dev/hk2-1.6.32/auto-depends/src/main/java/lh.jigsaw.hk2.autodepends
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/auto-depends/src/main/java/lh.jigsaw.hk2.autodepends/module-info.java ~/dev/hk2-1.6.32/auto-depends/src/main/java/lh.jigsaw.hk2.autodepends/
build
cd ~/dev/hk2-1.6.32/auto-depends/
mvn -Dmaven.test.skip=true clean install
HK2-Core
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/core/pom.xml ~/dev/hk2-1.6.32/core/
(update the libraryDirectory path for your set up / username, gedit  ~/dev/hk2-1.6.32/core/pom.xml & )


mkdir ~/dev/hk2-1.6.32/core/src/main/
mv  ~/dev/hk2-1.6.32/core/src/java ~/dev/hk2-1.6.32/core/src/main/
mkdir ~/dev/hk2-1.6.32/core/src/main/java/lh.jigsaw.hk2.core
mv  ~/dev/hk2-1.6.32/core/src/main/java/com ~/dev/hk2-1.6.32/core/src/main/java/lh.jigsaw.hk2.core/
cp  ~/dev/hk2-jigsaw-downloads/hk2-1.6.32/core/src/main/java/lh.jigsaw.hk2.core/module-info.java ~/dev/hk2-1.6.32/core/src/main/java/lh.jigsaw.hk2.core/
build
cd ~/dev/hk2-1.6.32/core/
mvn -Dmaven.test.skip=true clean install 

Add the adapter for Jigsaw:

The adapter only implements the minimum required to start HK2 over Jigsaw and inject a dependency in a program. It inspired by both the initial HK2 launcher and the OSGi adapter. The Jigsaw interaction bits are in JigsawFactory (obtain a library instance), JigsawModuleDefinition (obtain the inhabitants file content from the Jisaw library for a module), JigsawModulesRegistry (obtain a class loader for a module).
cp -r  ~/dev/hk2-jigsaw-downloads/hk2-jigsaw/jigsaw-adapter ~/dev/hk2-jigsaw/
cd ~/dev/hk2-jigsaw/jigsaw-adapter
mvn -Dmaven.test.skip=true clean install

Let's us it:

See  Worldclock on Jigsaw and HK2