Skip to content

Commit ab838d7

Browse files
authored
Merge pull request #1184 from sappo/master
Problem: Fatal exception when NativeLoader loads same jar-packaged library twice
2 parents a1ec69f + 703ac42 commit ab838d7

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

zproject_java.gsl

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ task generateJniHeaders(type: Exec, dependsOn: 'classes') {
170170
'src/main/java/$(name_path)/$(name:pascal).java'$(last ()?? ""? ",")
171171
. endfor
172172
]
173-
commandLine("javac", "-h", "$nativeIncludes", "-classpath", "$classpath:$appclasspath", *jniClasses)
173+
def utilityClasses = [
174+
'src/main/java/org/zeromq/tools/ZmqNativeLoader.java'
175+
]
176+
commandLine("javac", "-h", "$nativeIncludes", "-classpath", "$classpath:$appclasspath", *jniClasses, *utilityClasses)
174177
}
175178
tasks.withType(Test) {
176179
systemProperty "java.library.path", "/usr/lib:/usr/local/lib:$projectDir"
@@ -755,6 +758,37 @@ popd
755758
.endif
756759
.endmacro
757760

761+
.macro generate_native_loader ()
762+
. directory.create ("$(topdir)/src/main/java/org/zeromq/tools")
763+
. output "$(topdir)/src/main/java/org/zeromq/tools/ZmqNativeLoader.java"
764+
package org.zeromq.tools;
765+
766+
import java.util.Set;
767+
import java.util.HashSet;
768+
import org.scijava.nativelib.NativeLoader;
769+
770+
public class ZmqNativeLoader {
771+
772+
private static final Set<String> loadedLibraries = new HashSet<>();
773+
774+
public static void loadLibrary(String libname) {
775+
if (!loadedLibraries.contains(libname)) {
776+
if (System.getProperty("java.vm.vendor").contains("Android")) {
777+
System.loadLibrary(libname);
778+
} else {
779+
try {
780+
NativeLoader.loadLibrary(libname);
781+
} catch (Exception e) {
782+
System.err.println("[WARN] " + e.getMessage() +" from jar. Assuming it is installed on the system.");
783+
}
784+
}
785+
loadedLibraries.add(libname);
786+
}
787+
}
788+
789+
}
790+
.endmacro
791+
758792
.macro generate_class_in_java (class)
759793
. directory.create ("$(topdir)/src/main/java/$(name_path)")
760794
. output "$(topdir)/src/main/java/$(name_path)/$(my.class.name:pascal).java"
@@ -764,7 +798,7 @@ $(project.GENERATED_WARNING_HEADER:)
764798
package org.zeromq.$(project.prefix:c);
765799

766800
import java.util.stream.Stream;
767-
import org.scijava.nativelib.NativeLoader;
801+
import org.zeromq.tools.ZmqNativeLoader;
768802
. for project.use
769803
. if count (project->dependencies.class, class.project = use.project) > 0
770804
import org.zeromq.$(use.project).*;
@@ -777,27 +811,23 @@ implements AutoCloseable\
777811
. endif
778812
{
779813
static {
780-
if (System.getProperty("java.vm.vendor").contains("Android")) {
781-
System.loadLibrary("$(project.prefix:c)jni");
782-
} else {
783-
Stream.of(
814+
Stream.of(
784815
. for project.use
785816
"$(use.prefix:c)",
786817
. endfor
787818
"$(project.prefix:c)"
788819
)
789820
.forEach(lib -> {
790821
try {
791-
NativeLoader.loadLibrary(lib);
822+
ZmqNativeLoader.loadLibrary(lib);
792823
} catch (Exception e) {
793824
System.err.println("[WARN] " + e.getMessage() +" from jar. Assuming it is installed on the system.");
794825
}
795826
});
796-
try {
797-
NativeLoader.loadLibrary("$(project.prefix:c)jni");
798-
} catch (Exception e) {
799-
System.exit (-1);
800-
}
827+
try {
828+
ZmqNativeLoader.loadLibrary("$(project.prefix:c)jni");
829+
} catch (Exception e) {
830+
System.exit (-1);
801831
}
802832
}
803833
public long self;
@@ -990,6 +1020,7 @@ public class $(my.class.name:pascal)Test {
9901020
project.topdir = "bindings/jni"
9911021
directory.create (topdir)
9921022

1023+
generate_native_loader ()
9931024
for project.class
9941025
resolve_class (class)
9951026
if class.okay

0 commit comments

Comments
 (0)