felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rcbandit2 <peter.pen...@gmail.com>
Subject How to call Java Native Interface insight OSGI bundle
Date Wed, 22 Feb 2012 21:18:24 GMT

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: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Mime
View raw message