maven-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Gainty <mgai...@hotmail.com>
Subject RE: JNI jars dependencies
Date Fri, 04 Jan 2013 20:23:20 GMT

  > Date: Fri, 4 Jan 2013 11:54:46 -0800
> From: stuart@apl.washington.edu
> To: users@maven.apache.org
> Subject: Re: JNI jars dependencies
> 
> Hi from a newbie.MG>a newbie with extensive experience with maven and make files!
> 
> I too have been fighting with how best to develop maven artifacts 
> containing jni parts.  Though I found several useful posts on jni and 
> maven , e.g.
> 
> http://www.tricoder.net/blog/?p=197
> 
> http://docs.codehaus.org/display/MAVENUSER/Projects+With+JNI
> 
> http://www.humboldt.co.uk/2009/02/wrapping-a-native-library-with-maven.html
> 
> in the end I rolled my own solution, something I wanted to avoid.  My 
> goal was to produce usable artifacts that worked across platforms, ie 
> linux 32 and 64 bit and perhaps windows.  Here's some notes on my 
> experiences over the past 3-4 days.  My particular jni effort was to 
> 'Java-ify' an existing C library.
> 
> I isolated the Java classes which had native methods into a single Maven 
> module, so producing a single artifact.  I placed the Java sources under 
> the regular src/main/java.  In the pom, I used maven-native-plugin to 
> invoke javah to produce the headers (jn the default location 
> target/native/javah).  In the same pom, I then used the exec plugin to 
> invoke make in ./native/${os.name}.  Both of these are bound to the 
> compile phase, so a simple
> 
> mvn
> 
> will compile Java, run javah, then locate correct Makefile and run it.
> 
>    I then added makefiles to ./native/Linux and ./native/Windows.  In 
> the Linux makefile, I used VPATH to locate the C sources in 
> ${basedir}/src/main/c.  The final .so file (which has no platform/arch 
> encoded into its name, ie is just libfoo.so) is copied by the make into 
> ${basedir}/target/classes/META-INF/lib, so the package phase will locate 
> the .so at /META-INF/lib/libfoo.so, from which the nifty 
> com.wapmx.native loader can unpack it at runtime. MG>is this NativeLoader what you're
alluding toMG>http://dev.loci.wisc.edu/trac/software/browser/branches/maven/projects/native-library-util/src/main/java/com/wapmx/nativeutils/jniloader/NativeLoader.java?rev=7574
> 
> The whole artifact is then named
> 
> NAME-${os.arch}-${os.name}  and installed and/or deployed.  this is sort 
> of a poor man's AOL (from the nar plugin, which I ended up NOT using). MG>did'nt catch
the reasons why you do'nt want to use nar..explain please
> 
> Then a project/module which depends on this artifact simply uses the 
> name above.  It's a bit crude, but for 2 or 3 platforms maximum, I think 
> it will be manageable.
> 
> Points:
> 
> the javah invocation could have been done either from Maven or make.  I 
> chose to to it in Maven, mostly to avoid duplication across many 
> platform Makefiles. MG>smart ..OS and compiler specific variables should be aggregated
in OS and compiler specific profiles
> 
> I use the wapmx artifact to extract the native lib from the jar, better 
> than requiring LD_LIBRARY_PATH solutions.
> 
> My particular jni scenario required that the Java side maintain C 
> pointers (in both directions).  Knowing that these would be 64 bits wide 
> on 64 bit platforms, I had to use Java longs and jlong in the C code.  
> Compiling on 32 bit Linux, I then had to add
> 
> ifeq ($(shell uname -m),i686)
> # want any warning to raise error, but silence any 64/32 bit conversions
> CFLAGS += -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast
> endif
> 
> to the Makefile to silence the compiler's warnings.  I always compile 
> with -Werror (any warning is an error, fail to build)
> 
> In the C link phase in my makefiles, I statically linked the C library I 
> am wrapping, call it W.  To do this, I used an explicit file name, eg.
> 
> cc -o libfoo.so /path/to/libW.a my1.o my2.o
> 
> I tried fancy -Wl,-static and -Wl,-shared linker options but it always 
> failed to link.  I should point out that I had sources to libW, so could 
> configure/make it as desired.
> 
> 
> Then my end user (who is handed just a single jar) does not need any 
> libW.so at runtime.MG>whats inside the uber.jar?
MG>app code?
MG>JNI ?MG>How is the app PATHed to native binaries?
> 
> 
> Paths I investigated but did not finally use:
> 
> having the Java classes containing the native methods (call it A) and 
> the actual .so (call it B) as separate Maven modules, as explained in 
> the first url above. Then B depends upon A being built so that javah can 
> locate .class files, but then how do you run test cases in A, since you 
> need native code in B.MG>perhaps aggregate the plugins for B into a child module?
> 
> I did not use maven-nar-plugin, since as suggested, it is really a Maven 
> solution to wider native development.  I had a localised (or so I think) 
> jni issue.
> 
> I used maven-native-plugin over the antrun-plugin, which apparently 
> would also give access to javah (would this require an extra Ant 
> build.xml or can this be 'embedded' in the pom???) MG>forked ant targets cause classloader
issues, resource-limitation issues and passing maven-properties to ant build.xml and return
MG>back...unless there is a political reason to do so..stay with maven
> 
> Comments, suggestions welcomed
> 
> Stuart
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
> 
 		 	   		  
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message