jzy3d / jogl-maven-deployer

Scripts to make a maven distribution out of JOGL 2.4
6 stars 2 forks source link

Proposal: distinguish Maven artifacts using classifier, not artifactId #3

Open Birch-san opened 2 years ago

Birch-san commented 2 years ago

It's helpful for gluegen-rt-v2.4.0-rc4.jar and gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar to be installed to the same directory:

image

This enables compatibility with calls such as:

if (TempJarCache.initSingleton() && TempJarCache.isInitialized(true)) {
  boolean located = JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { jogamp.common.Debug.class }, null);
}

addNativeJarLibs locates gluegen-rt-v2.4.0-rc4.jar correctly, and assumes that gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar will be located next to it.

You can achieve this by making the two artifacts agree on artifactId, but differ by classifier:

"$MVN" install:install-file -DgroupId=org.jogamp.gluegen -DartifactId=gluegen-rt                                       -Dversion="$version" -Dfile="${LIB}/gluegen-rt.jar"                          -Dpackaging=jar
"$MVN" install:install-file -DgroupId=org.jogamp.gluegen -DartifactId=gluegen-rt -Dclassifier=natives-macosx-universal -Dversion="$version" -Dfile="${LIB}/gluegen-rt-natives-macosx-universal.jar" -Dpackaging=jar
"$MVN" install:install-file -DgroupId=org.jogamp.jogl -DartifactId=jogl-all                                            -Dversion="$version" -Dfile="${LIB}/jogl-all.jar"                            -Dpackaging=jar
"$MVN" install:install-file -DgroupId=org.jogamp.jogl -DartifactId=jogl-all      -Dclassifier=natives-macosx-universal -Dversion="$version" -Dfile="${LIB}/jogl-all-natives-macosx-universal.jar"   -Dpackaging=jar
jzy3d commented 2 years ago

Hi, Sorry for my late reply. I like the idea of using classifiers. I am interested of using them to indicate which JDK was used to build JOGL. To better understand your proposal : what is the purpose of the compatibility call you mention?

One reason for me to avoid doing this would be to keep JOGL working as it has been for years... lot of JOGL users are used to version 2.3.2 / published in 2015...

Birch-san commented 2 years ago

Without the fix above: JOGL throws an UnsatisfiedLinkError during startup, from JarUtil::fixNativeLibAttribs(String).
You can see the error with -Djogamp.debug.JarUtil=true.

The reason nobody noticed is because JarUtil::fixNativeLibAttribs(File) employs a try-catch, which swallows the error and resumes.
It's probably harmless, but it's fixable, and something that I noticed because I was looking for (other) UnsatisfiedLinkErrors in a program I was porting to M1.

The repro is simple…

Set an Exception breakpoint:

image

Run a simple program like this (enough to ensure that GLProfile's static block runs):

import com.jogamp.opengl.GLProfile;

public class Main {
    public static void main(String[] args) {
        System.out.println(GLProfile.isInitialized());
    }
}

It goes bang:

image

Because it tries to invoke JarUtil::fixNativeLibAttribs(String) without first running System.loadLibrary("gluegen_rt").

System.loadLibrary("gluegen_rt") only works if libgluegen_rt.dylib is present on your -Djava.library.path. But we can use gluegen idioms to get access to that library:

TempJarCache.initSingleton();
JNILibLoaderBase.addNativeJarLibs(new Class<?>[] { jogamp.common.Debug.class }, null);

JNILibLoaderBase::addNativeJarLibs is a helper which extracts gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar to a temporary directory, and loads the libgluegen_rt.dylib contained in that archive.

The convention for how to invoke JNILibLoaderBase::addNativeJarLibs is:

Now, maybe:

But this UnsatisfiedLinkError occurs in Live2D Cubism Editor (on 2.3.2), so it's definitely happening in production software.

One reason for me to avoid doing this would be to keep JOGL working as it has been for years

Is that satisfiable? From what I can tell (looking at Cubism Editor), the convention for loading native libs on 2.3.2 was:
put libgluegen-rt.jnilib somewhere on your -Djava.library.path
whereas for 2.4.0-rc4 it's:
_libgluegen_rt.dylib can be found inside gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar_

Nevertheless, I think you do have the option of publishing the artifact to both coordinates.

jzy3d commented 2 years ago

Thank you @Birch-san for the detailed explanations.

From what I can tell (looking at Cubism Editor), the convention for loading native libs on 2.3.2 was: put libgluegen-rt.jnilib somewhere on your -Djava.library.path whereas for 2.4.0-rc4 it's: libgluegen_rt.dylib can be found inside gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar

Since 2.3.2 (and even earlier), I have been used to only work with the jar files, letting JOGL deal with unpacking the native libraries to a tmp dir (which by the way fails on Ubuntu 18).

I tried reproducing the link error on my Mac M1 by adding the VM arg -Djogamp.debug.JarUtil=true, activated a conditional breakpoint on UnsatisfiedLinkError and started one of the Jzy3D samples. It actually starts correctly, no ULE, no hand. What I can read in console does not refer to ULE.

getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/com/jogamp/common/os/Platform.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/com/jogamp/common/os/Platform.class
getJarUri res: com.jogamp.common.os.Platform -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/com/jogamp/common/os/Platform.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/com/jogamp/common/os/Platform.class
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/jogamp/common/Debug.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/jogamp/common/Debug.class
getJarUri res: jogamp.common.Debug -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/jogamp/common/Debug.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4.jar!/jogamp/common/Debug.class
getJarName res: gluegen-rt-v2.4.0-rc4.jar
getJarFile.0: jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar!/
getJarFile.1: jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt/v2.4.0-rc4/gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar!/
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class
getJarUri res: jogamp.nativetag.common.macosx.universal.TAG -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class
getJarFile.0: jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class
getJarFile.1: jar:file:/Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/common/macosx/universal/TAG.class
getJarFile res: /Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar
JarUtil: extract: /Users/martin/.m2/repository/org/jogamp/gluegen/gluegen-rt-natives-macosx-universal/v2.4.0-rc4/gluegen-rt-natives-macosx-universal-v2.4.0-rc4.jar -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362, extractNativeLibraries true (natives/macosx-universal/), extractClassFiles false, extractOtherFiles false
JarUtil: JarEntry : META-INF/MANIFEST.MF other-file skipped
JarUtil: JarEntry : jogamp/nativetag/common/macosx/universal/TAG.class class-file skipped
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil: MKDIR (parent): natives/macosx-universal/libgluegen_rt.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libgluegen_rt.dylib - UnsatisfiedLinkError: com.jogamp.common.util.JarUtil.fixNativeLibAttribs(Ljava/lang/String;)Z
JarUtil: EXTRACT[1]: [gluegen_rt -> ] natives/macosx-universal/libgluegen_rt.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libgluegen_rt.dylib: 85840 bytes, addedAsNativeLib: true
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/nativewindow/Debug.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/nativewindow/Debug.class
getJarUri res: jogamp.nativewindow.Debug -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/nativewindow/Debug.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/nativewindow/Debug.class
getJarName res: jogl-all-v2.4.0-rc4.jar
getJarFile.0: jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4-natives-macosx-universal.jar!/
getJarFile.1: jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4-natives-macosx-universal.jar!/
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/opengl/Debug.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/opengl/Debug.class
getJarUri res: jogamp.opengl.Debug -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/opengl/Debug.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/opengl/Debug.class
getJarName res: jogl-all-v2.4.0-rc4.jar
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class
getJarUri res: jogamp.nativetag.opengl.macosx.universal.TAG -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class
getJarFile.0: jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class
getJarFile.1: jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar!/jogamp/nativetag/opengl/macosx/universal/TAG.class
getJarFile res: /Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar
JarUtil: extract: /Users/martin/.m2/repository/org/jogamp/jogl/jogl-all-natives-macosx-universal/v2.4.0-rc4/jogl-all-natives-macosx-universal-v2.4.0-rc4.jar -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362, extractNativeLibraries true (natives/macosx-universal/), extractClassFiles false, extractOtherFiles false
JarUtil: JarEntry : META-INF/MANIFEST.MF other-file skipped
JarUtil: JarEntry : jogamp/nativetag/opengl/macosx/universal/TAG.class class-file skipped
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libjogl_desktop.dylib - OK
JarUtil: EXTRACT[1]: [jogl_desktop -> ] natives/macosx-universal/libjogl_desktop.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libjogl_desktop.dylib: 1705368 bytes, addedAsNativeLib: true
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libjogl_mobile.dylib - OK
JarUtil: EXTRACT[2]: [jogl_mobile -> ] natives/macosx-universal/libjogl_mobile.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libjogl_mobile.dylib: 842984 bytes, addedAsNativeLib: true
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnativewindow_awt.dylib - OK
JarUtil: EXTRACT[3]: [nativewindow_awt -> ] natives/macosx-universal/libnativewindow_awt.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnativewindow_awt.dylib: 67896 bytes, addedAsNativeLib: true
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnativewindow_macosx.dylib - OK
JarUtil: EXTRACT[4]: [nativewindow_macosx -> ] natives/macosx-universal/libnativewindow_macosx.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnativewindow_macosx.dylib: 122912 bytes, addedAsNativeLib: true
JarUtil: JarEntry : isNativeLib true, isClassFile false, isDir false, isRootEntry false
JarUtil.fixNativeLibAttribs: /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnewt_head.dylib - OK
JarUtil: EXTRACT[5]: [newt_head -> ] natives/macosx-universal/libnewt_head.dylib -> /var/folders/d2/85g_sxm91rg71yyky4gg6l6h0000gn/T/jogamp_0000/file_cache/jln5800900738886518685/jln4676470397949810362/natives/macosx-universal/libnewt_head.dylib: 193424 bytes, addedAsNativeLib: true
getJarUri Default jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/newt/Debug.class
    -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/newt/Debug.class
getJarUri res: jogamp.newt.Debug -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/newt/Debug.class -> jar:file:/Users/martin/.m2/repository/org/jogamp/jogl/jogl-all/v2.4.0-rc4/jogl-all-v2.4.0-rc4.jar!/jogamp/newt/Debug.class
getJarName res: jogl-all-v2.4.0-rc4.jar

Why do you think we have difference between our two run?