Problem Description
Some BEAM modules are wrapper for 3rd party JARs, such as the NetCDF and HDF libraries. The HDF libraries also comprise platform-dependent native code in shared libararies. Their module layout in the final BEAM installation is as follows:
+-- beam-4.0
+-- modules
+-- lib-netcdf
| +-- module.xml
| +-- lib
| +-- nc_core.jar
|
+-- lib-hdf
+-- module.xml
+-- lib
+-- jhdf.jar
+-- jhdf5.jar
+-- win
| +-- jhdf.dll
| +-- jhdf5.dll
...
The corresponding Maven sub-modules look like this:
+-- beam-4.0
+-- pom.xml
+-- lib-netcdf
| +-- pom.xml
| +-- src/main/resources
| +-- modules.xml
| +-- lib
| +-- nc_core.jar
|
+-- lib-hdf
+-- pom.xml
+-- src/main/resources
+-- modules.xml
+-- lib
+-- jhdf.jar
+-- jhdf5.jar
+-- win
| +-- jhdf.dll
| +-- jhdf5.dll
...
While the layout of the final module in the BEAM installation directory can be more or less easily created using the maven-assembly-plugin, the all-in-one module approach causes severe problems for BEAM developers. BEAM developers should be able to set-up new maven projects with declared BEAM dependecies in their POMs, e.g.:
<project>
...
<dependencies>
<dependency>
<groupId>org.esa.beam</groupId>
<artifactId>beam-core</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>ncsa.hdf</groupId>
<artifactId>lib-hdf</artifactId>
<version>2.3</version>
</dependency>
...
</dependencies>
...
</project>
This will not work, because the lib-hdf contains the JARs and shared libraries. lib-hdf should instead be composed of Maven project dependencies to required artifacts. Otherwise the maven-idea-plugin and maven-eclipse-plugin cannot generate the appropriate classpath for the IDEA or Eclipse project files. Another problem is caused by the native libraries. These must be unpacked to a location accessible by the application at runtime.
Solution
In the POM of the lib-hdf module the HDF JARs from NCSA are declared as ordinary dependencies. Therefore they are manually installed in the local repository:
mvn install:install-file -Dfile=jhdf.jar -DgroupId=ncsa.hdf -DartifactId=jhdf -Dversion=2.3 mvn install:install-file -Dfile=jhdf5.jar -DgroupId=ncsa.hdf -DartifactId=jhdf5 -Dversion=2.3
We use the maven-dependency-plugin to copy the HDF artifacts into the resources directory in the generate-resources lifecycle phase. This way we don't need to keep copies of the JARs in our version control system. The maven-dependency-plugin is also used to unpack native code into the resources directory. Therefore, the native code is packed into a single ZIP and then manually installed in the local repository:
mvn install:install-file -Dfile=jhdf-nativecode.zip -DgroupId=ncsa.hdf -DartifactId=jhdf-nativecode-Dversion=2.3 -Dpackaging=zip mvn install:install-file -Dfile=jhdf5-nativecode.zip -DgroupId=ncsa.hdf -DartifactId=jhdf5-nativecode-Dversion=2.3 -Dpackaging=zip
Now developers can use a dependency to lib-hdf in their POM and automatically include the dependencies to the HDF JARs.
Finally, the HDF JARs must be able to locate the native code at runtime. If the application to be developed is a BEAM extension (target code located in BEAM's modules directory), native code is automatically located and loaded via Ceres module loading. For applications which simply use BEAM modules or for performing unit-level tests, the native code location for the HDF JARs must be specified as Java VM parameters as follows:
-Dncsa.hdf.hdflib.HDFLibrary.hdflib=C:/projects/beam-4.1/lib-hdf/src/main/resources/lib/win/jhdf.dll -Dncsa.hdf.hdf5lib.H5.hdf5lib=C:/projects/beam-4.1/lib-hdf/src/main/resources/lib/win/jhdf5.dll