We need help to get an URI handler for a Java application on macOS working.
We are implementing SSO for an existing Java application and after login in a browser we want to use an URI handler to be able to return to the Java application with some values passed.
We were able to implement this on Windows by registering an URI handler in the Windows registry. When navigating to the URI in the browser, a new instance of our application is started with the URI passed as parameters to the main method. The new instance can then send the necessary values from the URI to the already running instance and then exit.
On macOS we are able to register an URI scheme in the Info.plist file like this:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.company.ourscheme/string>
<key>CFBundleURLSchemes</key>
<array>
<string>ourscheme</string>
</array>
</dict>
</array>
As we understand it, the URI will not be passed as an argument to our Main method (it isn't for us). So, we have tried using the setOpenURIHandler in java.desktop
Desktop.getDesktop().setOpenURIHandler((event) -> {
System.out.println("Open URI: " + event.getURI());
// do something with the URI
});
as described by the answer given by Alex Suzuki here. The requirements are:
We have registered for public.data like this:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>public.data</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
</array>
</dict>
</array>
We have tried to minimize our application so it basically just opens a dialog and waits. The callback method would print and log any callback and any URI provided.
When we enter an URI in the browser:
ourscheme://testing
or use open on the command line:
open ourscheme://testing
We never get any callback at all. If the application is not running, it is started (but no callback). If the application is already running it does get focus (but no callback).
We have tested with a variety of URI's in case the DocumentTypes registration requires the URI to represent an existing document type, such as:
ourscheme://file.txt
Any idea what we are doing wrong? Are we on the right track here or is there any other strategies on how to solve this?
Worth to mention is perhaps that we have wrapped our Java application in a small C program which is our executable. The C program just launches Java with some parameters like this (I removed some error handling in the example, but the file is only 33 rows long):
int main(int argc, char *argv[])
{
// Set some variables used below ...
char *args[] = {java, concat("-Duser.dir=", userdir), "-Dsun.awt.disablegrab=true", concat("-Xdock:icon=", icon), "-Xdock:name=Our Product", "-Dcom.apple.macos.use-file-dialog-packages=true", "-Dcom.apple.macos.useSmallTabs=true", "-Dapple.laf.useScreenMenuBar=false", "-Dcom.apple.mrj.application.apple.menu.about.name=Our Product", "-Xms64M", "-Xmx1024M", "-jar", jar, "custom-argument", NULL};
execv(java, args)
return 0;
}
Could this C wrapper somehow affect the URI handler registration?
Thank you in advance for any help!
Environment:
macOS Monterey (M1, Aarch64) and Java 17
Could this C wrapper somehow affect the URI handler registration?
I can reproduce that using a bash
wrapper impacts the URI handler registration. Here's the test project:
https://github.com/tresf/OpenUriTest
Before (works fine):
mvn install
open -a OpenUriTest
open launchy:test
Changing the following line in pom.xml
will break setOpenURIHandler
.
<configuration>
<target>
<echo message="Clobbering JavaLauncher with our script file"/>
<!-- Note: Change "echo" to "cp" to break setOpenURIHandler -->
<exec executable="cp"> <!--- #### HERE #### -->
<arg value="JavaLauncher.sh"/>
<arg value="target/${project.artifactId}.app/Contents/MacOS/JavaLauncher"/>
</exec>
</target>
</configuration>
After (does NOT work):
mvn install
open -a OpenUriTest
open launchy:test