This time I'm working on very advanced task. I have to call JNI insight OSGI bundle.
I want to create OSGI bundle which can be deployed on Glassfish application server. My goal is to create Java <-> C bridge between OSGI application and C daemon. I'm going to do it in this way: 1. OSGI bundle will use JNI to call C methods from small .so file 2. The little .so file will use RPC using sockets to call functions from the C daemon. My biggest problem so far is how to implement OSGI bundle with JNI. There are no books with examples and there is no good tutorial which can help me. Here is what I have done: I created simple OSGI bundle with this POM file: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.DX_57.osgi.NB_27</groupId> <artifactId>NB_27</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <artifactId>NB_27-impl</artifactId> <packaging>bundle</packaging> <name>NB_27-impl</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>NB_27-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>build-native</id> <phase>process-classes</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <property name="native.classpath" refid="maven.compile.classpath" /> <echo file="${project.build.directory}/compile-classpath" message="${native.classpath}" /> <exec dir="src/main/native" executable="make" failonerror="true" /> </tasks> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Import-Package>${pom.groupId}.api, org.osgi.framework, org.apache.commons.collections, org.apache.commons.collections.buffer</Import-Package> <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> <Bundle-Activator>${pom.groupId}.impl.NetworkBridgeApp</Bundle-Activator> <Bundle-NativeCode> lib/libsqrt.so; osname=Linux;processor=x86 </Bundle-NativeCode> </instructions> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> <groupId>org.DX_57.osgi.NB_27</groupId> </project> I use maven-antrun-plugin to start Makefile which generates header file for the .so file. Here is the Makefile. #!/usr/bin/make -f # # Makefile for native stuff # # c files to compile C_SOURCES := sqrt.c # the name of the library to build LIBNAME := sqrt C_SOURCE_DIR := src C_GENSOURCE_DIR := src TARGET_DIR := ../../../target C_BUILD_DIR = $(TARGET_DIR)/native JAVA_BUILD_DIR = $(TARGET_DIR)/classes # the name of the file we build TARGET = $(JAVA_BUILD_DIR)/META-INF/lib/$(LIB_PREFIX)$(LIBNAME)$(LIB_EXTN) # find the jdk. if this doesn't work for you, define JAVA_HOME in your # environment or on the make command line JAVA_HOME ?= /opt/jdk1.7.0_02 # classpath for javah JAVAH_CLASSPATH = `cat $(TARGET_DIR)/compile-classpath` # tools and options CFLAGS = -Wall -fpic CPPFLAGS = -I$(C_SOURCE_DIR) -I$(C_GENSOURCE_DIR) -Iinclude \ -I$(JAVA_HOME)/include JAVAH = /opt/jdk1.7.0_02/bin/javah JAVAH_FLAGS += -classpath $(JAVAH_CLASSPATH) JAVAH_CMD = $(JAVAH) $(JAVAH_FLAGS) $(OUTPUT_OPTION) LDFLAGS = -shared LINK.so = $(CC) $(LDFLAGS) $(LD_LIBS) ifdef DEBUG CFLAGS += -g LDFLAGS += -g endif # os-dependent bits UNAME := $(shell uname) ifeq ($(UNAME),Linux) LIB_PREFIX = lib LIB_EXTN = .so CPPFLAGS += -I$(JAVA_HOME)/include/linux else ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) LIB_PREFIX = LIB_EXTN = .dll CPPFLAGS += -I$(JAVA_HOME)/include/win32 else f := $(error Platform $(UNAME) not supported) endif endif # we look in $(C_SOURCE_DIR) for c files... vpath %.c $(C_SOURCE_DIR) # convenience variables C_OBJFILES = $(addprefix $(C_BUILD_DIR)/,$(subst .c,.o,$(C_SOURCES))) # default target all: $(TARGET) # rule to compile the .c files $(C_BUILD_DIR)/%.o: %.c @mkdir -p `dirname $@` $(COMPILE.c) $(OUTPUT_OPTION) $< # link the C objects into a shared library $(TARGET): $(C_OBJFILES) $(LDLIBS) @mkdir -p `dirname $@` $(LINK.so) $(OUTPUT_OPTION) $^ # a rule to build the .h file with javah $(C_GENSOURCE_DIR)/org_DX_57_osgi_NB_27_impl_Sqrt.h: $(JAVA_BUILD_DIR)/org/DX_57/osgi/NB_27/impl/Sqrt.class rm -f $@ $(JAVAH) $(JAVAH_FLAGS) $(OUTPUT_OPTION) org.DX_57.osgi.NB_27.impl.Sqrt # the .o file depends on the .h file $(C_BUILD_DIR)/sqrt.o: $(C_GENSOURCE_DIR)/org_DX_57_osgi_NB_27_impl_Sqrt.h clean:: rm -f $(C_OBJFILES) rm -f $(TARGET) rm -f $(C_BUILD_DIR)/jnirules.mak This Makefile successfully extracts the header files and builds the .so file. I can successfully compile the entire bundle. The problem comes when I deploy the bundle on Glassfish server. It throws me an error message that this .so file cannot be found. I have configured the MANIFEST file to include JNI. I even tried to place the .so file in several locations insight the bundle but the error is still there. I know that usually for desktop applications environment variable LD_LIBRARY_PATH must be set but in this case the application is hosted in application server. Do you know how the problem could be solved? Here you can download the source code: http://www.2shared.com/file/1PEGooFJ/NB_27-impl.html Best wishes Peter -- View this message in context: http://old.nabble.com/How-to-call-Java-Native-Interface-insight-OSGI-bundle-tp33373923p33373923.html Sent from the Apache Felix - Users mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

