PhilippvK / playforia-minigolf

Client & Server for Minigolf Game known from Playforia/Playray/Appeli. Written in Java.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Maven generated dmg file is not working

pehala opened this issue · comments

As discussed in #36, it seems as the .dmg is not working correctly.

The problem is not really related to the DMG file. I just realized that non of the generated .jar files is executable on MacOS:

➜  client (master) ✗ java -jar target/client-1.0.jar
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: agolf/AGolf
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
	at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
	at java.lang.Class.getMethod0(Class.java:3018)
	at java.lang.Class.getMethod(Class.java:1784)
	at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: agolf.AGolf
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 7 more

Also I had to upgrade the version of launch4j in the pom.xml to the latest version because of the following error. Do you have a reason for using 1.5.1 instead of 1.7.25?

[ERROR] Failed to execute goal com.akathist.maven.plugins.launch4j:launch4j-maven-plugin:1.5.1:launch4j (windows-build) on project client: Failed to build the executable; please verify your configuration.: net.sf.launch4j.ExecException: java.io.IOException: Cannot run program "/Users/Philipp/.m2/repository/com/akathist/maven/plugins/launch4j/launch4j-maven-plugin/1.5.1/launch4j-maven-plugin-1.5.1-workdir-mac/bin/windres": error=86, Bad CPU type in executable -> [Help 1]

None, I copied the code for launch4j and it seemed to worked so I left it be :D

Do you have oracle java or openjdk? And is it java 8?

I found out that mvn compile exec:java does work without any problem but mvn package generates unusable JARs with the error message mentioned above when trying to run the artifact.

I was able to "fix" this by removing the following code section from the client/pom.xml:

        <resources>
            <resource>
                <directory>res</directory>
            </resource>
        </resources>

Can you explain if this is really required and how can this result in an error on MacOS (I am using Maven version 3.6.3)

Hmmmm. Of course this does not really solve the situation as the Client as able to launch but fails to load the resources....

Do you have oracle java or openjdk? And is it java 8?

➜  client (master) ✗ java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.265-b01, mixed mode)

The Launch4j error should not be related to the JAR problem. I think this was only because the version of the plugin was so old that it shipped 32bit binaries instead of 64 bit ones.

Additionally I was wondering if the MANIFEST.MF files are still in use. They seem to be a bit redundant:

./server/META-INF/MANIFEST.MF
./shared/src/META-INF/MANIFEST.MF
./manifests/agolf/META-INF/MANIFEST.MF
./editor/META-INF/MANIFEST.MF
./editor/src/META-INF/MANIFEST.MF

The section is there because resources are kept in non standard location, interesting that it launches without them tho. I will check if I have openjdk or oracle java on my PC, it might be openjdk specific problem.

The manifests are there because they didn't cause any problem for me, so I simply ignored them. Removing them.might solve the issue since maven should generate proper manifest regardless.

Try looking at maven shade plugin as it is responsible for packaging all the things into jar. With current configuration it throws warnings about overlapping Manifest but the warning says it shouldn't cause any problems.

UPDATE:

After removing the manifests the jar file launches and also the .xml files containing the translations are found when launched via java -jar .... What is not working now is the Image Fetching:

Uncaught error fetching image:
java.lang.NullPointerException
	at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:116)
	at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:126)
	at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:263)
	at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)
	at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)

I will have a look at your changes from #36

Try looking at maven shade plugin as it is responsible for packaging all the things into jar. With current configuration it throws warnings about overlapping Manifest but the warning says it shouldn't cause any problems.

Just to document the warning here:

[INFO] --- maven-shade-plugin:3.2.4:shade (default) @ client ---
[INFO] Including io.netty:netty:jar:3.6.6.Final in the shaded jar.
[WARNING] client-1.0.jar, netty-3.6.6.Final.jar define 1 overlapping resource:
[WARNING]   - META-INF/MANIFEST.MF
[WARNING] maven-shade-plugin has detected that some class files are
[WARNING] present in two or more JARs. When this happens, only one
[WARNING] single version of the class is copied to the uber jar.
[WARNING] Usually this is not harmful and you can skip these warnings,
[WARNING] otherwise try to manually exclude artifacts based on
[WARNING] mvn dependency:tree -Ddetail=true and the above output.
[WARNING] See http://maven.apache.org/plugins/maven-shade-plugin/
[INFO] --- maven-shade-plugin:3.2.4:shade (default) @ editor ---
[INFO] Including org.moparforia:shared:jar:1.0 in the shaded jar.
[WARNING] editor-1.0.jar, shared-1.0.jar define 5 overlapping classes and resources:
[WARNING]   - META-INF/MANIFEST.MF
[WARNING]   - META-INF/maven/org.moparforia/shared/pom.properties
[WARNING]   - META-INF/maven/org.moparforia/shared/pom.xml
[WARNING]   - org.moparforia.shared.Tools
[WARNING]   - org.moparforia.shared.Track
[WARNING] maven-shade-plugin has detected that some class files are
[WARNING] present in two or more JARs. When this happens, only one
[WARNING] single version of the class is copied to the uber jar.
[WARNING] Usually this is not harmful and you can skip these warnings,
[WARNING] otherwise try to manually exclude artifacts based on
[WARNING] mvn dependency:tree -Ddetail=true and the above output.
[WARNING] See http://maven.apache.org/plugins/maven-shade-plugin/
[INFO] --- maven-shade-plugin:3.2.4:shade (default) @ server ---
[INFO] Including io.netty:netty:jar:3.6.6.Final in the shaded jar.
[INFO] Including org.mongodb:mongo-java-driver:jar:3.6.0 in the shaded jar.
[INFO] Including org.mongodb.morphia:morphia:jar:1.2.2 in the shaded jar.
[INFO] Including cglib:cglib-nodep:jar:2.2.2 in the shaded jar.
[INFO] Including com.thoughtworks.proxytoys:proxytoys:jar:1.0 in the shaded jar.
[INFO] Including org.moparforia:shared:jar:1.0 in the shaded jar.
[WARNING] cglib-nodep-2.2.2.jar, mongo-java-driver-3.6.0.jar, morphia-1.2.2.jar, netty-3.6.6.Final.jar, proxytoys-1.0.jar, server-1.0.jar, shared-1.0.jar define 1 overlapping resource:
[WARNING]   - META-INF/MANIFEST.MF
[WARNING] maven-shade-plugin has detected that some class files are
[WARNING] present in two or more JARs. When this happens, only one
[WARNING] single version of the class is copied to the uber jar.
[WARNING] Usually this is not harmful and you can skip these warnings,
[WARNING] otherwise try to manually exclude artifacts based on
[WARNING] mvn dependency:tree -Ddetail=true and the above output.
[WARNING] See http://maven.apache.org/plugins/maven-shade-plugin/

Try looking at the ImageManager method defineImage, that should be the root cause. I will investigate that once I get back.to the computer.

I wasn't able to reproduce it with OpenJDK on Ubuntu. I also looked at the generate Manifest files and they seem alright and the missing class is present in the jar, so it is probably mac only issue, but I have no idea why.

openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~20.04-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

Small progress: Fixed the image loading on macOS by replacing

Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("/AGolf/picture/"+method1597(imageFileName)));

with

Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("/agolf/picture/"+method1597(imageFileName)));

Case sensitivity lol...

Still have to figure something else but I will let you know when I made progress.

Still no success but it seems to be about case sensitivity as well.

The contents of the res directory are placed at the root directory inside the JAR file causing to have for example AGolf and agolf in the same directory.

@pehala Could you possibly provide me the output of jar tvf target/client-1.0.jar for your toolchain? (It's quite long, so you might have to use f.e. https://pastebin.com)

http://one-line-it.blogspot.com/2013/01/mac-os-x-java-becomes-case-insensitive.html

For classes, it is a little bit trickier since the class name is also the file name. Java's case sensitivity becomes the filesystem's case sensitivity. Linux is case sensitive and therefore, you can have two classes in the same package sharing the same name (with different case). Mac OS X is not and therefore you can't. It won't compile and Eclipse for Mac doesn't actually let you do it.

Here is an example of the situation.

Contents of the JAR file:

ADraw/
ADraw/picture/
ADraw/picture/background.gif
ADraw/picture/bg-password.gif
ADraw/picture/game-info.gif
ADraw/picture/game-tools-off.gif
ADraw/picture/game-tools-on.gif
AGolf/
AGolf/AGolf.class
AGolf/Conn.class
AGolf/GameApplet.class
AGolf/GameContainer.class
AGolf/LobbySelectPanel.class

How it should look like:

ADraw/
ADraw/picture/
ADraw/picture/background.gif
ADraw/picture/bg-password.gif
ADraw/picture/game-info.gif
ADraw/picture/game-tools-off.gif
ADraw/picture/game-tools-on.gif
agolf/
agolf/AGolf.class
agolf/Conn.class
agolf/GameApplet.class
agolf/GameContainer.class
agolf/LobbySelectPanel.class

Here it is https://pastebin.com/3LuNC8Ns, but it looks like it is identical to yours.

If the problem is with case sensitivity, we can simply rename resources to lowercase, or separate resources into custom folder.

My workaround was renaming res/Agolf to res/AGolf_res but I would like to do anything more consistent. I would consider merging the resources and class names info a single folder if all other approaches do not seem to work cross platform.

Like you already motioned, separating the resources to a custom folder would be a good idea. Do you have a recommendation for the directory name and how to realize this in maven?

I can create reorganization PR which would address it. I wanted to do rename directories to proper maven ones like src/main/java and src/main/resources anyway.

I can create reorganization PR which would address it. I wanted to do rename directories to proper maven ones like src/main/java and src/main/resources anyway.

That would be so great! I hope the effort to do so is not to much...