Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Birch-san opened this issue Jan 20, 2022 · 3 comments
Open

Comments

@Birch-san
Copy link

Birch-san commented Jan 20, 2022

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
Copy link
Owner

jzy3d commented Feb 15, 2022

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
Copy link
Author

Birch-san commented Feb 19, 2022

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:

  • pass a reference to any class contained in gluegen-rt-v2.4.0-rc4.jar
  • gluegen computes "gluegen-rt-v2.4.0-rc4-natives-macosx-universal.jar", by combining "gluegen-rt-v2.4.0-rc4.jar" with our platform information
  • gluegen expects these files to be in the same directory
    • that's why we need them to have the same artifactId, but with different classifier!

Now, maybe:

  • this doesn't need solving (just let it swallow the error harmlessly)
  • this is evidence that JOGL was being used wrong (GLProfile accessed without doing some preparatory step?)

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
Copy link
Owner

jzy3d commented Feb 22, 2022

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants