[SOLVED] Missing JAR in desktop deployment

No I have not tried to build Maud on my computer. My point is that Gradle absolutely does not do anything magic to control the order the JVM finds classes because it can’t.

The reason it can’t is as Paul says. Classloading is machine dependant. In practice you might predict the order (like specifying manifest attributes) but in theory there are no guarantees since classloaders are allowed to do parallel loading.

So maybe that is the difference you experience? The ant and gradle builds maybe sets up the manfest attribute differently?

Just re-reading this post. Is there any possibility of seeing the ant file that you are using?

Looking-down-the-straw from a distance, it sounds like somehow the fileset that copies libraries from dist/lib to the various platform distributions is being set up in a way that excludes or filters the Minie jar, perhaps based on some peculiarity with it’s name?

1 Like

That’s the most sensible suggestion I’ve heard so far. The XML files are unchanged from JME’s BasicGameTemplate, which can be found at https://github.com/jMonkeyEngine/sdk/tree/v3.2.2-stable-sdk1/BasicGameTemplate

And here is my project.properties file:

annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
application.desc=An editor for jMonkeyEngine3 animated models.
application.homepage=https://github.com/stephengold/Maud
application.splash=assets/Textures/icons/Maud.png
application.title=Maud
application.vendor=sgold
assets.jar.name=assets.jar
assets.excludes=
assets.folder.name=assets
assets.compress=true
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
bundle.jre.enabled=true
compile.on.save=true
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
    ${run.classpath}
debug.test.classpath=\
    ${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/${application.title}.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.jME-TTF-v2.12.jar=S:\\saved downloads\\jars\\Google.com\\jME-TTF-v2.12\\jME-TTF-v2.12.jar
file.reference.jme3-utilities-debug-0.9.9.jar=S:\\releases\\debug\\0.9.9\\jme3-utilities-debug-0.9.9.jar
file.reference.jme3-utilities-heart-2.18.0.jar=S:\\releases\\heart\\2.18.0\\jme3-utilities-heart-2.18.0.jar
file.reference.jme3-utilities-nifty-0.9.1.jar=S:\\releases\\nifty\\0.9.1\\jme3-utilities-nifty-0.9.1.jar
file.reference.jme3-utilities-ui-0.7.0.jar=S:\\releases\\ui\\0.7.0\\jme3-utilities-ui-0.7.0.jar
file.reference.jme3_physicsloader-0.5.jar=S:\\saved downloads\\jars\\BinTray.com\\jme3_physicsloader-0.5.jar
file.reference.jme3_xbuf_loader-0.9.1.jar=S:\\saved downloads\\jars\\BinTray.com\\jme3_xbuf_loader-0.9.1.jar
file.reference.jme3_xbuf_rt-0.9.1.jar=S:\\saved downloads\\jars\\BinTray.com\\jme3_xbuf_rt-0.9.1.jar
file.reference.logback-classic-1.2.3.jar=S:\\saved downloads\\jars\\BinTray.com\\logback-classic-1.2.3.jar
file.reference.logback-core-1.2.3.jar=S:\\saved downloads\\jars\\BinTray.com\\logback-core-1.2.3.jar
file.reference.Minie-0.6.5.jar=S:\\releases\\Minie\\0.6.5\\Minie-0.6.5.jar
file.reference.Minie.jar=S:\\releases\\Minie\\0.6.5\\Minie.jar
file.reference.nifty-1.4.2.jar=S:\\saved downloads\\jars\\BinTray.com\\nifty-1.4.2.jar
file.reference.nifty-default-controls-1.4.2.jar=S:\\saved downloads\\jars\\BinTray.com\\nifty-default-controls-1.4.2.jar
file.reference.nifty-style-black-1.4.2.jar=S:\\saved downloads\\jars\\BinTray.com\\nifty-style-black-1.4.2.jar
file.reference.protobuf-java-3.0.0.jar=S:\\saved downloads\\jars\\BinTray.com\\protobuf-java-3.0.0.jar
file.reference.sfntly.jar=S:\\saved downloads\\jars\\Google.com\\jME-TTF-v2.12\\sfntly.jar
file.reference.SkyControl-0.9.16.jar=S:\\releases\\SkyControl\\0.9.16\\SkyControl-0.9.16.jar
file.reference.slf4j-api-1.7.25.jar=S:\\saved downloads\\jars\\BinTray.com\\slf4j-api-1.7.25.jar
file.reference.Wes-0.3.9.jar=S:\\releases\\Wes\\0.3.9\\Wes-0.3.9.jar
file.reference.xbuf-0.9.1.jar=S:\\saved downloads\\jars\\BinTray.com\\xbuf-0.9.1.jar
file.reference.xpp3-1.1.4c.jar=S:\\saved downloads\\jars\\BinTray.com\\xpp3-1.1.4c.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
jar.compress=true
jar.index=${jnlp.enabled}
javac.classpath=\
    ${libs.jme3-core.classpath}:\
    ${libs.jme3-blender.classpath}:\
    ${libs.jme3-desktop.classpath}:\
    ${libs.jme3-effects.classpath}:\
    ${libs.jme3-lwjgl.classpath}:\
    ${libs.jme3-plugins.classpath}:\
    ${libs.jme3-terrain.classpath}:\
    ${file.reference.jme3_physicsloader-0.5.jar}:\
    ${file.reference.jme3_xbuf_rt-0.9.1.jar}:\
    ${file.reference.slf4j-api-1.7.25.jar}:\
    ${file.reference.logback-core-1.2.3.jar}:\
    ${file.reference.logback-classic-1.2.3.jar}:\
    ${file.reference.jme3_xbuf_loader-0.9.1.jar}:\
    ${file.reference.nifty-1.4.2.jar}:\
    ${file.reference.nifty-default-controls-1.4.2.jar}:\
    ${file.reference.nifty-style-black-1.4.2.jar}:\
    ${file.reference.protobuf-java-3.0.0.jar}:\
    ${file.reference.xbuf-0.9.1.jar}:\
    ${file.reference.xpp3-1.1.4c.jar}:\
    ${file.reference.sfntly.jar}:\
    ${file.reference.jME-TTF-v2.12.jar}:\
    ${file.reference.jme3-utilities-heart-2.18.0.jar}:\
    ${file.reference.jme3-utilities-debug-0.9.9.jar}:\
    ${file.reference.Minie.jar}:\
    ${file.reference.Minie-0.6.5.jar}:\
    ${file.reference.jme3-utilities-ui-0.7.0.jar}:\
    ${file.reference.jme3-utilities-nifty-0.9.1.jar}:\
    ${file.reference.SkyControl-0.9.16.jar}:\
    ${file.reference.Wes-0.3.9.jar}
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked -Xlint:deprecation
javac.deprecation=true
javac.external.vm=false
javac.processorpath=\
    ${javac.classpath}
javac.source=1.8
javac.target=1.8
javac.test.classpath=\
    ${build.classes.dir}:\
    ${javac.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
jme.project.version=3.1
jnlp.codebase.type=local
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
linux-x64.app.enabled=true
linux-x86.app.enabled=true
macosx-x64.app.enabled=true
main.class=maud.Maud
meta.inf.dir=${src.dir}/META-INF
manifest.file=MANIFEST.MF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
    ${build.classes.dir}:\
    ${assets.folder.name}:\
    ${javac.classpath}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-ea
run.test.classpath=\
    ${javac.test.classpath}:\
    ${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
windows-x64.app.enabled=true
windows-x86.app.enabled=true

There are also some XML files that probably were added by NetBeans. I think the key one is desktop-deployment-impl.xml, which looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!--desktop-deployment-impl.xml v1.0-->
<project name="desktop-deployment-impl" basedir="..">
    <target name="-desktop-deployment" depends="-extract-native-binaries, -create-launcher-jvmargs, -test-platforms-enabled, -windows-x86-app, -windows-x64-app, -linux-x86-app, -linux-x64-app, -macosx-x64-app"/>
    
    <target name="-windows-x86-app" if="is.windows-x86.app.enabled">
        <echo>Windows 32bit Application Creation</echo>
        <copy file="resources/desktop-deployment/windows-x86/package.cfg" tofile="resources/desktop-deployment/windows-x86/_package.cfg">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class.launcher}"/>
                <replacestring from="$${launcher.jvmargs}" to="${launcher.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
            </filterchain>
        </copy>
        
        <zip destfile="${dist.dir}/${application.title}-Windows-x86.zip">
            <zipfileset file="resources/desktop-deployment/windows-x86/stub.exe" filemode="755" fullpath="${application.title}/${application.title}.exe"/>
            <zipfileset file="resources/desktop-deployment/windows-x86/_package.cfg" fullpath="${application.title}/app/package.cfg"/>
            <zipfileset file="resources/desktop-deployment/windows-x86/icon.ico" fullpath="${application.title}/${application.title}.ico"/>
            <zipfileset file="${dist.jar}" prefix="${application.title}/app"/>
            <zipfileset dir="${dist.dir}/lib" excludes="${deployment.jarexcludes}" prefix="${application.title}/app/lib"/>
            <zipfileset dir="${build.dir}/natives/windows-x86" prefix="${application.title}/app" erroronmissingdir="false"/>
        </zip>
        <delete file="resources/desktop-deployment/windows-x86/_package.cfg"/>
        <antcall target="-package-windows-x86-jre"/>
    </target>
    
    <target name="-package-windows-x86-jre" if="is.bundle.jre.enabled">
        <untar src="resources/desktop-deployment/jre-windows-x86.tar.gz" dest="build/jre" compression="gzip"/>
        <dirset dir="build/jre" id="dirId-windows-x86">
            <include name="jre*"/>
        </dirset>
        <property name= "dirName-windows-x86" refid= "dirId-windows-x86"/>
        <zip destfile="${dist.dir}/${application.title}-Windows-x86.zip" update="true">
            <zipfileset dir="build/jre/${dirName-windows-x86}" prefix="${application.title}/runtime/jre"/>
        </zip>
        <delete dir="build/jre"/>
    </target>
    
    <target name="-windows-x64-app" if="is.windows-x64.app.enabled">
        <echo>Windows 64bit Application Creation</echo>
        <copy file="resources/desktop-deployment/windows-x64/package.cfg" tofile="resources/desktop-deployment/windows-x64/_package.cfg">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class.launcher}"/>
                <replacestring from="$${launcher.jvmargs}" to="${launcher.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
            </filterchain>
        </copy>
        
        <zip destfile="${dist.dir}/${application.title}-Windows-x64.zip">
            <zipfileset file="resources/desktop-deployment/windows-x64/stub.exe" filemode="755" fullpath="${application.title}/${application.title}.exe"/>
            <zipfileset file="resources/desktop-deployment/windows-x64/_package.cfg" fullpath="${application.title}/app/package.cfg"/>
            <zipfileset file="resources/desktop-deployment/windows-x64/icon.ico" fullpath="${application.title}/${application.title}.ico"/>
            <zipfileset file="${dist.jar}" prefix="${application.title}/app"/>
            <zipfileset dir="${dist.dir}/lib" excludes="${deployment.jarexcludes}" prefix="${application.title}/app/lib"/>
            <zipfileset dir="${build.dir}/natives/windows-x64" prefix="${application.title}/app" erroronmissingdir="false"/>
        </zip>
        <delete file="resources/desktop-deployment/windows-x64/_package.cfg"/>
        <antcall target="-package-windows-x64-jre"/>
    </target>
    
    <target name="-package-windows-x64-jre" if="is.bundle.jre.enabled">
        <untar src="resources/desktop-deployment/jre-windows-x64.tar.gz" dest="build/jre" compression="gzip"/>
        <dirset dir="build/jre" id="dirId-windows-x64">
            <include name="jre*"/>
        </dirset>
        <property name= "dirName-windows-x64" refid= "dirId-windows-x64"/>
        <zip destfile="${dist.dir}/${application.title}-Windows-x64.zip" update="true">
            <zipfileset dir="build/jre/${dirName-windows-x64}" prefix="${application.title}/runtime/jre"/>
        </zip>
        <delete dir="build/jre"/>
    </target>
    
    <target name="-linux-x86-app" if="is.linux-x86.app.enabled">
        <echo>Linux 32bit Application Creation</echo>
        <copy file="resources/desktop-deployment/linux-x86/package.cfg" tofile="resources/desktop-deployment/linux-x86/_package.cfg">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class.launcher}"/>
                <replacestring from="$${launcher.jvmargs}" to="${launcher.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
            </filterchain>
        </copy>
        
        <zip destfile="${dist.dir}/${application.title}-Linux-x86.zip">
            <zipfileset file="resources/desktop-deployment/linux-x86/stub" filemode="755" fullpath="${application.title}/${application.title}"/>
            <zipfileset file="resources/desktop-deployment/linux-x86/_package.cfg" fullpath="${application.title}/app/package.cfg"/>
            <zipfileset file="${dist.jar}" prefix="${application.title}/app"/>
            <zipfileset dir="${dist.dir}/lib" excludes="${deployment.jarexcludes}" prefix="${application.title}/app/lib"/>
            <zipfileset dir="${build.dir}/natives/linux-x86" prefix="${application.title}/app" erroronmissingdir="false"/>
        </zip>
        <delete file="resources/desktop-deployment/linux-x86/_package.cfg"/>
        <antcall target="-package-linux-x86-jre"/>
    </target>
    
    <target name="-package-linux-x86-jre" if="is.bundle.jre.enabled">
        <untar src="resources/desktop-deployment/jre-linux-x86.tar.gz" dest="build/jre" compression="gzip"/>
        <dirset dir="build/jre" id="dirId-linux-x86">
            <include name="jre*"/>
        </dirset>
        <property name= "dirName-linux-x86" refid= "dirId-linux-x86"/>
        <zip destfile="${dist.dir}/${application.title}-Linux-x86.zip" update="true">
            <zipfileset dir="build/jre/${dirName-linux-x86}" excludes ="bin/*" prefix="${application.title}/runtime/jre"/>
            <zipfileset dir="build/jre/${dirName-linux-x86}" includes ="bin/*" filemode="755" prefix="${application.title}/runtime/jre"/>
        </zip>
        <delete dir="build/jre"/>
    </target>
    
    <target name="-linux-x64-app" if="is.linux-x64.app.enabled">
        <echo>Linux 64bit Application Creation</echo>
        <copy file="resources/desktop-deployment/linux-x64/package.cfg" tofile="resources/desktop-deployment/linux-x64/_package.cfg">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class.launcher}"/>
                <replacestring from="$${launcher.jvmargs}" to="${launcher.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
            </filterchain>
        </copy>
        
        <zip destfile="${dist.dir}/${application.title}-Linux-x64.zip">
            <zipfileset file="resources/desktop-deployment/linux-x64/stub" filemode="755" fullpath="${application.title}/${application.title}"/>
            <zipfileset file="resources/desktop-deployment/linux-x64/_package.cfg" fullpath="${application.title}/app/package.cfg"/>
            <zipfileset file="${dist.jar}" prefix="${application.title}/app"/>
            <zipfileset dir="${dist.dir}/lib" excludes="${deployment.jarexcludes}" prefix="${application.title}/app/lib"/>
            <zipfileset dir="${build.dir}/natives/linux-x64" prefix="${application.title}/app" erroronmissingdir="false"/>
        </zip>
        <delete file="resources/desktop-deployment/linux-x64/_package.cfg"/>
        <antcall target="-package-linux-x64-jre"/>
    </target>
    
    <target name="-package-linux-x64-jre" if="is.bundle.jre.enabled">
        <untar src="resources/desktop-deployment/jre-linux-x64.tar.gz" dest="build/jre" compression="gzip"/>
        <dirset dir="build/jre" id="dirId-linux-x64">
            <include name="jre*"/>
        </dirset>
        <property name= "dirName-linux-x64" refid= "dirId-linux-x64"/>
        <zip destfile="${dist.dir}/${application.title}-Linux-x64.zip" update="true">
            <zipfileset dir="build/jre/${dirName-linux-x64}" excludes ="bin/*" prefix="${application.title}/runtime/jre"/>
            <zipfileset dir="build/jre/${dirName-linux-x64}" includes ="bin/*" filemode="755" prefix="${application.title}/runtime/jre"/>
        </zip>
        <delete dir="build/jre"/>
    </target>

    <target name="-macosx-x64-app" if="is.macosx-x64.app.enabled">
        <echo>MacOSX Application Creation</echo>
        <loadresource property="jfxdeploy.jvmargs">
            <propertyresource name="run.jvmargs"/>
            <filterchain>
                <tokenfilter>
                    <filetokenizer/>
                    <replacestring from=" " to="&lt;/string&gt;&lt;string&gt;"/>
                </tokenfilter>
            </filterchain>
        </loadresource>
        <antcall target="-update-macosx-x64-plist-with-runtime"/>
        <antcall target="-update-macosx-x64-plist-without-runtime"/>
        <zip destfile="${dist.dir}/${application.title}-MacOSX.zip">
            <zipfileset file="resources/desktop-deployment/macosx-x64/stub" filemode="755" fullpath="${application.title}.app/Contents/MacOS/JavaAppLauncher"/>
            <zipfileset file="resources/desktop-deployment/macosx-x64/_Info.plist" fullpath="${application.title}.app/Contents/Info.plist"/>
            <zipfileset file="resources/desktop-deployment/macosx-x64/icon.icns" fullpath="${application.title}.app/Contents/Resources/GenericApp.icns"/>
            <zipfileset file="${dist.jar}" prefix="${application.title}.app/Contents/Java"/>
            <zipfileset dir="${dist.dir}/lib" excludes="${deployment.jarexcludes}" prefix="${application.title}.app/Contents/Java/lib"/>
            <zipfileset dir="${build.dir}/natives/macosx-x64" prefix="${application.title}.app/Contents/Java" erroronmissingdir="false"/>
        </zip>
        <delete file="resources/desktop-deployment/macosx-x64/_Info.plist"/>
        <antcall target="-package-macosx-x64-jre"/>
    </target>
    
    <target name="-update-macosx-x64-plist-with-runtime" if="is.bundle.jre.enabled">
        <!--key>JVMRuntime</key>
        <string>jdk1.8.0_31.jdk</string-->
        <copy file="resources/desktop-deployment/macosx-x64/Info.plist" tofile="resources/desktop-deployment/macosx-x64/_Info.plist">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class}"/>
                <replacestring from="$${run.jvmargs}" to="${jfxdeploy.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jfxdeploy.jvmargs}" to="-Xnoagent"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
                <replacestring from="&lt;!--jvmruntime--&gt;" to="&lt;key&gt;JVMRuntime&lt;/key&gt;&#13;  &lt;string&gt;jre.jre&lt;/string&gt;"/>
            </filterchain>
        </copy>
    </target>
    
    <target name="-update-macosx-x64-plist-without-runtime" unless="is.bundle.jre.enabled">
        <copy file="resources/desktop-deployment/macosx-x64/Info.plist" tofile="resources/desktop-deployment/macosx-x64/_Info.plist">
            <filterchain>
                <replacestring from="$${main.class}" to="${main.class}"/>
                <replacestring from="$${run.jvmargs}" to="${jfxdeploy.jvmargs}"/>
                <replacestring from="$${application.title}" to="${application.title}"/>
                <replacestring from="$${jfxdeploy.jvmargs}" to="-Xnoagent"/>
                <replacestring from="$${jar.name}" to="${application.title}.jar"/>
            </filterchain>
        </copy>
    </target>
    
    <target name="-package-macosx-x64-jre" if="is.bundle.jre.enabled">
        <untar src="resources/desktop-deployment/jre-macosx-x64.tar.gz" dest="build/jre" compression="gzip"/>
        <dirset dir="build/jre" id="dirId-macosx-x64">
            <include name="jre*"/>
        </dirset>
        <property name= "dirName-macosx-x64" refid= "dirId-macosx-x64"/>
        <zip destfile="${dist.dir}/${application.title}-MacOSX.zip" update="true">
            <zipfileset dir="build/jre/${dirName-macosx-x64}/Contents/Home" excludes ="bin/*" prefix="${application.title}.app/Contents/PlugIns/jre.jre/Contents/Home/jre"/>
            <zipfileset dir="build/jre/${dirName-macosx-x64}/Contents/Home" includes ="bin/*" filemode="755" prefix="${application.title}.app/Contents/PlugIns/jre.jre/Contents/Home/jre"/>
            <zipfileset file="build/jre/${dirName-macosx-x64}/Contents/Info.plist" fullpath="${application.title}.app/Contents/PlugIns/jre.jre/Contents/Info.plist"/>
            <zipfileset dir="build/jre/${dirName-macosx-x64}/Contents/MacOS" prefix="${application.title}.app/Contents/PlugIns/jre.jre/Contents/MacOS"/>
        </zip>
        <delete dir="build/jre"/>
    </target>
    
    <target name="-test-platforms-enabled">
        <condition property="is.windows-x86.app.enabled">
            <istrue value="${windows-x86.app.enabled}"/>
        </condition>
        <condition property="is.windows-x64.app.enabled">
            <istrue value="${windows-x64.app.enabled}"/>
        </condition>
        <condition property="is.linux-x86.app.enabled">
            <istrue value="${linux-x86.app.enabled}"/>
        </condition>
        <condition property="is.linux-x64.app.enabled">
            <istrue value="${linux-x64.app.enabled}"/>
        </condition>
        <condition property="is.macosx-x64.app.enabled">
            <istrue value="${macosx-x64.app.enabled}"/>
        </condition>
        <condition property="is.bundle.jre.enabled">
            <istrue value="${bundle.jre.enabled}"/>
        </condition>
    </target>

    <target name="-create-launcher-jvmargs">
        <script language="javascript">
            <![CDATA[
            var args = project.getProperty("run.jvmargs");
            var res = args.split(" ");
            var out = "";
            for (var i = 1; i < res.length+1; i++) {
                out = out + "jvmarg." + i + "=" + res[i-1] + "\r\n";
            }
            project.setProperty("launcher.jvmargs", out);
            ]]>
        </script>
        <loadresource property="main.class.launcher">
            <propertyresource name="main.class"/>
            <filterchain>
                <tokenfilter>
                    <filetokenizer/>
                    <replacestring from="." to="/"/>
                </tokenfilter>
            </filterchain>
        </loadresource>
    </target>
    
    <target name="-extract-native-binaries">
        <java outputproperty="deployment.jarexcludes" dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="getjarexcludes"/>
        </java>        
        <java dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="Windows32"/>
            <arg value="${build.dir}/natives/windows-x86"/>
        </java>
        <java dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="Windows64"/>
            <arg value="${build.dir}/natives/windows-x64"/>
        </java>
        <java dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="Linux32"/>
            <arg value="${build.dir}/natives/linux-x86"/>
        </java>
        <java dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="Linux64"/>
            <arg value="${build.dir}/natives/linux-x64"/>
        </java>
        <java dir="${basedir}" classname="com.jme3.system.ExtractNativeLibraries" fork="true" failonerror="false" classpath="${dist.jar}">
            <arg value="MacOSX64"/>
            <arg value="${build.dir}/natives/macosx-x64"/>
        </java>
    </target>
</project>

Right here. the property deployment.jarexcludes is set in calls to the classes

com.jme3.system.ExtractNativeLibraries &
com.jme3.system.NativeLibraryLoader.

Essentially, this entire build system assumes that Native libraries have two components:

  • An ‘API’ jar, which has all of the JNI *.class files, as well as any ‘ergonomics’ wrapper over them, e.g. jme3-bullet
  • A ‘native package’ jar, which includes the actual native libraries, including any JNI callback stubs, e.g. jme3-bullet-native

The ant task copies all native libraries to ${build.dir}/natives/$PLATFORM during the earlier build steps, and then excludes the .jar file from the deployment list during this step.

Your work-around works because the A1 jar is not listed in the places that check for native libraries. It’s therefore ignored, and just copied blindly with the rest of the /lib/*

I’m not sure if this assumption should be treated as a bug, or a (poorly documented) feature. If it’s a bug, there needs to be code to remove the native files from the jar before it is copied to the deployment location, to avoid wasted distribution bandwidth.

2 Likes

Thank you @sailsman63 for digging into this.

In order to conform to the expectations/assumptions of desktop deployment, I could split the Minie library into multiple JARs. My only reluctance is because it would introduce yet another opportunity for version mismatches between JARs.