1 项目结构
在maven项目中新建2个模块
xml1 2 3
| - parent - jni - native
|
1.1 parent pom
xml1 2 3 4
| <modules> <module>native</module> <module>jni</module> </modules>
|
1.2 jni pom
xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.github.bannirui</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> </parent>
<artifactId>jni</artifactId> <packaging>jar</packaging>
<dependencies> <dependency> <groupId>com.github.fommil</groupId> <artifactId>jniloader</artifactId> <version>1.1</version> </dependency> </dependencies>
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.7</version> <configuration> <systemPropertyVariables> <java.library.path>${project.build.directory}/classes</java.library.path> </systemPropertyVariables> </configuration> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.10</version> <executions> <execution> <id>copy</id> <phase>compile</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>com.zto.ts</groupId> <artifactId>native</artifactId> <version>1.0-SNAPSHOT</version> <type>so</type> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}/classes</outputDirectory> <destFileName>libdistance.so</destFileName> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
|
1.3 native pom
见下文。
完整Makefile如下
makefile1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| SRC_DIR = $(shell pwd) PACKAGE_NAME = com.zto.route.scheme PACKAGE_DIR = $(subst .,/,$(PACKAGE_NAME)) CLASS_NAME = Distance
default: export CLASSPATH=$(SRC_DIR)/jni/src/main/java/$(PACKAGE_DIR) cd $(SRC_DIR)/jni/src/main/java/$(PACKAGE_DIR) && javac -d $(SRC_DIR)/jni/src/main/java/$(PACKAGE_DIR) $(CLASS_NAME).java cd $(SRC_DIR)/jni/src/main/java && javah $(PACKAGE_NAME).$(CLASS_NAME) mv $(SRC_DIR)/jni/src/main/java/com_zto_route_scheme_$(CLASS_NAME).h $(SRC_DIR)/native/src/main/c/jni/ rm -rf $(SRC_DIR)/jni/src/main/java/com/zto/route/scheme/com
.PHONY: clean clean: rm -rf $(SRC_DIR)/jni/src/main/java/com/zto/route/scheme/com rm -rf $(SRC_DIR)/jni/src/main/java/$(PACKAGE_DIR)/*.class rm -rf $(SRC_DIR)/jni/src/main/java/*.h
|
2.1 定义Java native方法
正常情况下,源码中都是有package包名的,在源码中定义native方法。
xml1 2 3 4 5 6
| - jni - src - main - java - com.github.bannirui - A.java
|
2.2 声明native方法原型
java1
| private static native double a(double d1, double d2, double d3, double d4);
|
2.3 在A.java同级目录下编译为字节码class文件
shell1
| jni/src/main.java/com/github/bannirui/> javac A.java
|
2.4 在包路径前执行javah
因为javah生成的.h文件需要包名+类名,所以必须在包括全包名的路径下执行javah命令,在src/java目录下执行javah命令。
一直报错找不到类文件,经过排查是少了CLASSPATH,因此先指定环境变量CLASSPATH
shell1
| jni/src/main/java/> javah 包名.A
|
2.5 完善源码A
3 cpp实现
3.1 将.h文件拷贝到native
上面的Makefile已经将文件移动好了。
xml1 2 3 4 5 6
| - native - src - main - c - jni - com_github_bannirui_A.h
|
3.2 .c文件定义实现
xml1 2 3 4 5 6 7
| - native - src - main - c - jni - com_github_bannirui_A.h - com_github_bannirui_A.c
|
4 maven插件打包
4.1 先将native单独install或deploy
- 如果仅仅是在本地执行或者目的是终将项目打包成jar包,那么install到maven的本地repo就行
- 如果将来是要在公司的远程运维环境进行打包,那么就deply到私服
xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.zto.ts</groupId> <artifactId>route-service</artifactId> <version>1.0-SNAPSHOT</version> </parent>
<artifactId>native</artifactId> <packaging>so</packaging>
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> </plugin>
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>native-maven-plugin</artifactId> <version>1.0-alpha-8</version> <extensions>true</extensions> <configuration> <compilerProvider>generic-classic</compilerProvider> <compilerExecutable>gcc</compilerExecutable> <linkerExecutable>gcc</linkerExecutable> <sources> <source> <directory>${basedir}/src/main/c/jni</directory> <fileNames> <fileName>com_zto_route_scheme_Distance.c</fileName> </fileNames> </source> </sources> <compilerStartOptions> <compilerStartOption>-I ${JAVA_HOME}/include/</compilerStartOption> <compilerStartOption>-I ${JAVA_HOME}/include/linux/</compilerStartOption> <compilerStartOption>-I ${JAVA_HOME}/include/darwin/</compilerStartOption> <compilerStartOption>-I /usr/lib/jvm/java-8-openjdk-amd64/include</compilerStartOption> <compilerStartOption>-I /usr/lib/jvm/java-8-openjdk-amd64/include/linux</compilerStartOption> </compilerStartOptions> <compilerEndOptions> <compilerEndOption>-shared</compilerEndOption> <compilerEndOption>-fPIC</compilerEndOption> </compilerEndOptions> <linkerStartOptions> <linkerStartOption>-I ${JAVA_HOME}/include/</linkerStartOption> <linkerStartOption>-I ${JAVA_HOME}/include/linux/</linkerStartOption> <linkerStartOption>-I ${JAVA_HOME}/include/darwin/</linkerStartOption> <compilerStartOption>-I /usr/lib/jvm/java-8-openjdk-amd64/include</compilerStartOption> <compilerStartOption>-I /usr/lib/jvm/java-8-openjdk-amd64/include/linux</compilerStartOption> </linkerStartOptions> <linkerEndOptions> <linkerEndOption>-shared</linkerEndOption> <linkerEndOption>-fPIC</linkerEndOption> </linkerEndOptions> </configuration> </plugin> </plugins> </build>
<distributionManagement> </distributionManagement> </project>
|
4.2 parent group的package
对整个项目进行package,最终打包成jar包