Connecting dots from self-contained Java application to Mac OS installation - macos

I am not a Mac owner and am putting myself through a crash course to get up to speed (e.g., reading "Switching to the Mac"), to give you an indication of my current level of understanding. The access I have to a physical Mac is limited, so I am trying to connect as many dots as possible before my next session with my friend's computer.
I have: a file folder containing all resources needed for a self-contained application written with Java (OpenJDK 11, JavaFX 11). The JLINK tool was successfully used to create this file folder, and it holds all necessary Java libraries as well as the code I wrote for the application. The executable resides in a subfolder: /bin. The program runs perfectly well on the Mac when the executable is run.
I want: something that is easy to download, install and run.
I'm unclear about what needs to be done to get this. The road map seems to have two main steps:
the file folder needs to be converted into something that responds as if it were an application (e.g., a Bundle? or an .app?)
the resulting folder-as-executable can be shipped via either .dmg or .pkg
For the second part, I've researched and found tools such as Packages or create-dmg. It seems to me these tools are pretty straightforward and shouldn't be too difficult to learn to use. (Just have to pick one or the other or something similar.)
For the first part, I'm on shaky conceptual ground. I've found info about Bundles, but no tutorials, walk-throughs or examples. It looks like a key step is understanding how to make a proper Info.plist file, but doing this properly looks tricky. Also, I'm not clear on how the resulting Bundle will become an .app file or if it needs to, or if there is another, more direct way to make my file folder be viewed by the OS as an application.
Some hand-holding or references to tutorials or even assurance that I am on the right track (if that is the case) would be much appreciated. Thanks!
The Java Deployment guide from Oracle relies heavily on ANT, but doesn't cover the case of a self-contained, customized JVM via JLINK well enough for me to decipher. So, I've taken the approach of trying to learn/understand the necessary steps using command-line commands.

While creating a Bundle is certainly an option, there is an easier way.
Step one is to make an .app manually. An answer to this question: "How to make a Mac OS X .app with a shell script?" goes over the basic steps. The Java file system that results from jlinking has a folder /bin in which there is a bash file that runs the program. This file should be moved to the outermost folder, and it should be named the desired name of the application. The bash file itself will have to be edited and "/bin" added to the address in last command so that the executable will be found. In addition, the folder itself will have to be renamed to be the same as the bash file, but with .app added as an extension.
The next thing I wanted to have was a custom icon. The question "Include icon in manually created app bundle" shows how to do this.
For the next step I made use of the program "Packages". I'm a bit confused about where I downloaded this from (there seem to be multiple sites), but here is a link to the manual. This tool allowed me to create a .pkg file that, when executed, installs my .app in the Applications folder. Then I compressing the .pkg file (to .zip) and made it available at a URL for downloading.
I've had a friend do a test download and install, and the program works!
This isn't meant to be a complete tutorial, and there are a few steps more that I want to figure out pertaining to sandboxing and sealing, but I believe this is a reasonable roadmap that can be used for simpler jlinked Java applications for Mac distribution.

Related

Where do resource files go when developing Mac apps?

I'm new to developing Mac OSX apps via Delphi (Berlin) and don't know where to put resource files. In Windows I can write ImageControl1.LoadFromFile('aFile.png'); and know that's referencing the directory where my executable is located. Or I can do something like make and reference the path to a separate directory where I'm putting resources.
But I don't know where to put resources or how their paths work when developing on a Windows machine for an app that'll be compiled and run on a Mac. I tried putting an image file in the Delphi project's OSX subdirectory as well as entering a complete path, i.e., LoadFromFile('path/goes/here'). I also tried using forward and backward slashes in the path name expression. In each case I got an error (when compiling for Mac, not Windows). I'm sort of thinking the files should live on the Mac somewhere...but I'm lost.
I'm hoping someone could tell me where to put these kinds of resource files, or how to properly reference them, when developing Mac apps on a Windows machine (or, alternatively, a good reference or two that'll explain it to me ... I looked online but couldn't find an answer).
There's some info about the structure of macOS app bundles, here:
https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
In the Delphi Deployment Manager, resources can be deployed to a remote path of:
Contents\Resources\
And subfolders thereof. The following code should return the root of the .app package:
NSStrToStr(TNSBundle.Wrap(TNSBundle.OCClass.mainBundle).bundlePath)
Add /Contents/Resources (and applicable subfolders) to that path, and you can load the deployed files from there

Few general questions about JavaFX capabilities

I'm using JavaFX to build a GUI for the software I'm working on. I call it software but it's actually a series of automated steps, compiled into a standalone .exe file. I have about 6 of these executable files, which is why I'm building a GUI to act as the front-end, main menu of sorts.
Ideally I'd have the entire package (GUI, exes) combined into one file Jar which I'd then send to clients, or wrap it with JSmooth or Launch4j.
Questions:
1) Is it possible to combine all 6 .exe files into a package along with the GUI.? So if I click button 2 on the GUI, it runs .exe #2, etc. Which concepts should I understand?
2) Is this best practice, or is there a better method? I'm new to Java which is why I haven't built the entire software with it, just the GUI.
3) I've read that its best to extract the exe from the parent jar (or exe?) into a temp file on the users PC. Is this correct? Even for multiple wrapped exes?
Any answer is helpful. I'm trying to avoid building something only to realize I can't do what I needed. Thanks
It would be much easier to write an answer if you were a bit more specific regarding what those 6 .exe files do. Nevertheless, a few things can be pointed out. Answers are in the same order as questions.
Yes, you can package exe files into a jar. No, you can't run exe from within the jar. A common solution is to unpack exe either temporarily (while your application is active) or permanently, and then tell OS to execute it.
I'm not entirely sure what "best practice" refers to in your question. Ideally, your logic (back-end) code would be written in Java and all your 6 exe files would be a part of a single Java application. I respect that you are new to Java, so in your particular case having a front-end to your executables is perfectly fine. However, do keep in mind that your solution is Windows specific, unless you plan to provide other OS executables too.
Yes, you will need to extract the exe files. It doesn't really matter what parent executable you use (exe or jar). For the sake of simplicity, I'd go with the jar, because you won't need to use any 3rd party software to build such a jar.
Just to sum up, considering your situation, package your JavaFX app and the .exe files into a single executable jar. When the user needs to execute an ".exe", extract that ".exe" into the same directory where JavaFX is running from. When the app exits, delete all ".exe" files from that directory

How do I make an executable that will add my Automator service which runs a bash script?

My friends are losing points in their computer science classes because their submission graders decompress and read zip files, which are obfuscated by a bunch of Apple metadata crap generated from zipping a file through the right-click contextual menu in Finder.
I've written a bash script to zip only unhidden files from a specific directory, and I've added a contextual menu service through Automator so this script can be run from right clicking a file.
The problem is I don't want to manually copy over all this stuff and make Automations on each computer my friends use. I'd like to leverage make or some similar utility to make an executable that will add the bash file and automator menu service to any computer the executable is opened from.
I'm lightly familiar with make (more familiar with rake), but I can't find out how to package the automator service and install it on their machine through an executable.
You'll want to package your automator application and script(s) into an Installer Package (.pkg). The best way to achieve this is to understand some general concepts, the commands to build one, and by checking out some tutorials or other relevant information.
I recommend for creating your first Installer Package using a utility
such as Packages (open-source and free), which has excellent
documentation, and is less complicated than using the command
line tools. Basically it puts a nice gui around the Apple tools which
are somewhat nonintutive by themselves.
Building Installer Packages is not the easiest thing to do your first time, and it might take a bit of patience to finally get it right. Once you've successfully created one you should have a good grasp on what is involved in putting them together along with the concept behind it all. At the very least, this information hopefully points you in the right direction regarding your question, and/or gives you a better idea of how to accomplish what you want to do.

Application permission issues on OS X, when distributing application

we are making an Application for OS X, however, when the .app is copied on another MAC, we have problems with reading and writing files
on one MAC, everything works great from the start...
the other one will not write certain files and another 2mac will not write certain different files
if i go to show application contents and wants to edit the file by myself, i get a writing permission denied
how to distribute an MAC application so there are no such issues? so all files can be read and write by the current user
does there have to be some authorization or code sign, or smth. different in this form, in addition to normal code?
thank you
It sounds like your application tries to write files within its own application bundle. The correct solution here is: DON'T DO THAT! The only time your application bundle should be written to is when it's installed or updated.
Files that the application needs to write to should be stored in the user's home folder, generally under ~/Library. See this note in Apple's dev docs.
Preference and settings files in ~/Library/Preferences/<appbundleid>.plist; use NSUserDefaults.
Data the app manages for the user in ~/Library/Application Support/<appname> (the docs say to use the bundleid, but everyone -- Apple included -- uses the app name instead).
Cache files in ~/Library/Caches/<appbundleid>.
Temp files, use NSTemporaryDirectory
If you need to share settings & files between users, that should generally go in /Library/Application Support/<appname>, except that you really shouldn't be doing that at all.
In the past I've always used PackageMaker to create installers. An installation package can authenticate with root privileges so you can set permissions after the install. I don't have it in front of me right now but if you look around you should be able to see a Post-Installer script line. Write a shell script that manually sets the permissions of each file you have in question and then have the package execute that script after the install is finished.
You can find PackageMaker at /Developer/Applications/Utilities/PackageMaker

cocoa + .app file

i have an executable for my cocoa application as xyz.app file. But when i copy this on windows, it is showing this as a directory with all the resource files and stuff. Is there any way to create a single file executable on mac also (like .exe file on windows) so as to disable the user from seeing the resource files and other files?
Thanks
You talking about a Bundle, which is a folder that is given an extension and the OS treats it as if it is a single file, while in reality it is a folder with resources in it. The NIB files are stored in this bundle as well as your executable and the info.plist file. This is just the way apps work in Cocoa.
The only way around it would be to write your app in a different language, but i'm not sure which, if any, will give you a single file executable.
What are you storing in your app directory that you don't want people to have access to?
There are ridiculously complicated ways to do that, sure. For example, you could gzip all your resource files and decompress them at runtime. But there's no good reason to do so — all it does is make more work for you, introduce additional complexity and make your app slow. Adobe doesn't do this, Microsoft doesn't do this, micro-ISVs don't do this — it's just not advisable.

Resources