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

add Mac OSX application creation script #750

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

wright
Copy link

@wright wright commented May 23, 2021

This merge request adds a Mac OSX app generation script and supporting icons to the distribution.

It works by downloading and running the jar2app program, which should be cross platform (but a Mac will be required to test the resulting app). jar2app is deleted when the script completes.

Running Digital as a Mac app might resolve some of the strange invisible Folder issues.

The makeDigitalMacApp.sh script is currently included in the Target.zip package and can be run by the end user, so there is no Travis-CI integration required.

@codecov-commenter
Copy link

codecov-commenter commented May 23, 2021

Codecov Report

Merging #750 (6b30d45) into master (85e4908) will decrease coverage by 0.0%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##             master    #750     +/-   ##
==========================================
- Coverage      56.8%   56.8%   -0.1%     
- Complexity     6493    6496      +3     
==========================================
  Files           678     678             
  Lines         34824   34859     +35     
  Branches       4682    4683      +1     
==========================================
+ Hits          19811   19824     +13     
- Misses        13828   13848     +20     
- Partials       1185    1187      +2     
Impacted Files Coverage Δ
...va/de/neemann/digital/draw/shapes/OutputShape.java 62.2% <0.0%> (-0.7%) ⬇️
...n/digital/gui/components/graphics/MoveFocusTo.java 0.0% <0.0%> (ø)
...gui/components/modification/ModifyInsertWires.java 0.0% <0.0%> (ø)
...ain/java/de/neemann/digital/core/element/Keys.java 97.5% <0.0%> (+<0.1%) ⬆️
src/main/java/de/neemann/digital/core/io/Out.java 82.0% <0.0%> (+0.2%) ⬆️
src/main/java/de/neemann/digital/core/io/In.java 90.6% <0.0%> (+0.2%) ⬆️
...ava/de/neemann/digital/draw/shapes/InputShape.java 30.3% <0.0%> (+2.4%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 85e4908...6b30d45. Read the comment docs.

@hneemann
Copy link
Owner

Thanks for this contribution.
However, there is a problem with this: Java has changed its distribution model with version 14. The favored way to distribute a java desktop application is now to build a binary with jpackage/jlink which are both part of the JDK. The created binary also contains the runtime environment. The JRE as an individually installable runtime environment no longer exists as of java 14. The problem is that the creation of this binary must happen on the respective target system.
So a build system would have to be used, which offers a Windows, Linux and MacOs system to create the three binaries.
This could be implemented on Travis CI, but Travis CI has announced to limit its free offer due to too much misuse, so that it is currently unclear whether the effort of an implementation on Travis CI is still worth the effort.
In this situation, I don't really want to add alternative build processes, but rather wait until the situation is sorted out, and then use jpackage and jlink.

@wright
Copy link
Author

wright commented May 24, 2021

This MR adds a script that allows a Mac OS end user to repackage the JAR file that Digital currently distributes to them (in Digital.zip) to work more conveniently on their OS. It uses the existing JRE on the end users system, just as using the JAR file does.

This may not be the favored way to distribute the application, but I think it is an improvement on the current way for Mac OS users.

@hneemann
Copy link
Owner

But why not use jpackage and jlink?

@wright
Copy link
Author

wright commented May 25, 2021

The main reason that I did not use jpackage is because it was not installed on my Mac. I think Apple only distributes the older Java 1.8 (which I had installed). Java 1.8 is sufficient to run Digital, but does not include jpackage.

If other Mac users are like me, they will need to install the newer JDK to run jpackage. I did that, and changed the makeDigitalMacApp.sh script to call it:

jpackage --input . \
  --name Digital \
  --main-jar Digital.jar \
  --icon "macosx/Digital.icns" \
  --mac-package-name "Digital" \
  --type dmg \
  --java-options '--enable-preview'

This worked, but took the 3.7 MB Digital.jar file and turned it into a 63 MB disk image. The disk image must be mounted, and then the 149 MB Digital.app application need to be dragged to the location where it will be run. Jpackage bundles the Java runtime with the application (so that it can be redistributed, but I think that is unnecessary since the end user is running this instead of the Travis build system).

For comparison, jar2app does not require installing a new JDK, and creates a 4 MB Digital.app file in the same location as the light app wrappers for Linux and Windows: Digital.sh and Digital.exe. Jar2app uses the existing Java runtime. The Mac app generated by jar2app works like Digital's Linux and Windows wrappers.

@hneemann
Copy link
Owner

Is it possible to create a wrapper that does not contain the jar file?
So that a small wrapper loads the jar file from disk? In this case you could create and distribute the wrapper only once, without the user having to create the wrapper himself.

And I agree with you: Creating these huge files that contain the complete JRE I don't like either. But I'm afraid this is now the recommended way to distribute a Java desktop app.

@wright
Copy link
Author

wright commented May 26, 2021

I don't think it is possible to create a normal Mac application that does not contain the jar file.

Applications on Macs are really directories with a specific structure. Mac users expect to be able to drag an app (directory) to a new location, and have it still work. Ideally, they can "uninstall" it by dragging it to the trash.

For example, the Digital.app created by the jar2app program is:

$ du -ak Digital.app
20      Digital.app/Contents/MacOS/JavaAppLauncher
20      Digital.app/Contents/MacOS
0       Digital.app/Contents/PlugIns
336     Digital.app/Contents/Resources/Digital.icns
4       Digital.app/Contents/Resources/en.lproj/Localizable.strings
4       Digital.app/Contents/Resources/en.lproj
340     Digital.app/Contents/Resources
3588	Digital.app/Contents/Java/Digital.jar
3588	Digital.app/Contents/Java
4       Digital.app/Contents/Info.plist
3952    Digital.app/Contents
3952    Digital.app

There are only 5 files in the directory tree:

  • Digital.app/Contents/Java/Digital.jar: the jar file that we want to package
  • Digital.app/Contents/MacOS/JavaAppLauncher: a Mac executable that knows how to locate the JRE and properly launch jar files (I'm not sure exactly where this comes from - jar2app apparently found it in my installed JRE when it created the app)
  • Digital.app/Contents/Resources/Digital.icns: a binary file with the app's icon in Mac format
  • Digital.app/Contents/Resources/en.lproj/Localizable.strings: a 3 line text file with a few error messages
  • Digital.app/Contents/Info.plist: an XML file with some app information

One option that might be workable is to distribute a copy of Digital.app with the other build artifacts, after replacing the Digital.jar file with the new version. Copying Digital.jar into Digital.app/Contents/Java should work on Linux.

I will zip the Digital.app Mac application (directory) and attach it in case you want to take a closer look.

Digitalapp..zip

@hneemann
Copy link
Owner

hneemann commented Jun 6, 2021

Is a macOS app simply a zip file with a certain structure?
In this case, I could add the required files to the repository and create the macOS app zip file during the build.

@wright
Copy link
Author

wright commented Jun 6, 2021

A Mac OS app is simply a directory with a certain structure (not zipped). It could be zipped for distribution, and unzipped before it is executed. But since the distribution (Digital.zip) is already compressed, that seems unnecessary.

@hneemann
Copy link
Owner

hneemann commented Jun 6, 2021

If you simply replace the Digital.jar in your app directory with the latest pre-release jar file found here, will it still work?

@wright
Copy link
Author

wright commented Jun 6, 2021

Yes, that worked.

@hneemann
Copy link
Owner

I have added a new assembly to create a zip file for the Mac that contains the AppLauncher you created.
Could you please try it out and see how it behaves?

Digital.app.zip

hneemann added a commit that referenced this pull request Jun 10, 2021
@wright
Copy link
Author

wright commented Jun 10, 2021

The assembly you created seem to work well for me. The App shows up with an icon, and starts when double-clicked. It seems to run normally after that.

Like other unsigned Mac applications, it pops up a security dialog box when it is first run. The way this is bypassed is to start the App the first time by right clicking (or control clicking) on it and selecting "Open" from the context menu. Then it will give the option of proceeding after warning that "this was downloaded from the Internet on ...". This is normal for a Mac; I am just letting you know in case someone who does not know this asks you about it.

I see that you put the component libraries, examples, and release notes inside the App. This has the advantage of the files following the App around if the user drags it somewhere to install it. I'm not sure how Digital finds it default components. I have previously run a downloaded version and a version I compiled myself on this computer, so it is possible that Digital is finding some other version than the one inside the app. It would be good to test this on a computer that has never run Digital before.

The Mac file manager (inexplicably called "Finder") handles applications differently from normal files and directories. For example, it shows your Digital.app directory as the embedded icon with "Digital" written below it. This is normal for Macs. To open the .app directory to see what is in it, a Mac user needs to right click (or control click) on it and select "Show Package Contents" from the menu that pops up. I suspect this is NOT something that normal non-developer Mac users know about. So, I think Mac users would probably not find these examples and release notes. It does not hurt to leave them there, but I suggest including Digital.app next to the examples and release notes and the Windows version (Digital.exe) in the target/Digital.zip file built by maven. That way, a Mac user is more likely to notice them.

hneemann added a commit that referenced this pull request Jun 10, 2021
@wright
Copy link
Author

wright commented Jun 10, 2021

I borrowed a Mac that had never run Digital to test it, and I'm having problems.

Double-clicking DIgital.app pops up a dialog box that says "Unable to locate Java Runtime Environment" (presumably because Java has never been installed on the computer). I downloaded and installed jdk-16.0.1_osx_x64_bin.dmg. I then did the right-click, Open, Proceed step to bypass the security check, but it still does not run, popping up a Dialog box that says "Unable to load Java Runtime Environment".

I can start java from the command line, and I can run Digital with "java -jar Digital.app/Contents/Java/Digital.jar". It seems like copying the Jar file and relying on an existing version Contents/MacOS/JavaAppLauncher will not work.

@hneemann
Copy link
Owner

Too bad.
It seems that one has to stick to the recommended way and build a package that contains the JRE. This will create very large files, but it will work everywhere.

@wright
Copy link
Author

wright commented Jun 10, 2021

Does the recommended way require building the package on MacOS, and can your CI system do that?

@wright
Copy link
Author

wright commented Jun 10, 2021

I spoke too soon when I said it did not work earlier (I shouldn't test without sufficient coffee).

I installed the JDK on the borrowed Mac, when I should have installed the JRE. After installing jre-8u291-macos-x64.dmg downloaded from Oracle, your assembly seems to work normally.

@hneemann
Copy link
Owner

Does the recommended way require building the package on MacOS, and can your CI system do that?

Yes it requires running the packaging on the target system.
But as far as I know, TravisCI and also GitHub Actions are able to do this.

@hneemann
Copy link
Owner

I have reworked the layout of the MacOS package.
What do you think about it?

Digital_MacOS.zip

@wright
Copy link
Author

wright commented Jun 11, 2021

I like it. It works well on both Macs I can test with.

Since it is not a signed Mac application, it pops up a security dialog box the first time it is run. I will show you what that looks like in case someone asks you about it. Double-clicking on the application as you normally would to start it shows this on my computer:
doubleClickOpen

If I right-click (or control-click for Macs without a decent mouse) and choose "Open", this is the dialog box that appears:
controlClickOpen

After clicking the "Open" button, the program starts normally. After that, it will start normally when double-clicked.

@hneemann
Copy link
Owner

@wright

I like it. It works well on both Macs I can test with.

Then I will merge my branch. Thanks for creating the necessary files and helping with testing.

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

Successfully merging this pull request may close these issues.

None yet

3 participants