B4J Question How to hide Java icon from Dock in MacOS

Status
Not open for further replies.

Markos

Active Member
Licensed User
Longtime User
Hi All,

I researched for hours and still no solution how to hide or remove the Java icon from appearing when running a Java based App on the mac..

There are several solutions proposed online none of which works for me I'm using JDK11.x on Catalina Mac OSX

The most common proposed solution is to set the system property apple.awt.UIElement=true

I've tried it via a VM argument as java -jar -Dapple.awt.UIElement=true javaname.jar (and alternativelyapple.awt.UIElement="true")
also

SetSystemProperty("apple.awt.UIElement", "true") in B4J at the beginning of AppStart and still the Java appears in the Dock.

Other suggestions to try apple.awt.headless=true or java.awt.headless=true with no luck.

Has anyone found a solution for this challenge?

More Info:

My App uses JavaFX components and it seems JavaFX currently doesnt support Dock Icon Less capability. Having said that is their a work around I can do in either B4J code or in the scripts calling the Jar to not have the Java Coffee icon appear in the dock alongside my running App Icon.
 
Last edited:

Markos

Active Member
Licensed User
Longtime User
There are some thoughts to launch the Java app under java.awt app apply the SetSystemProperty("apple.awt.UIElement", "true") then launch the javafx based app. Is there someway to implement that using b4j?
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Is the approach below shown in java achievable for a B4j app

awt to launch javafx app:
/**
 - This class is intended to start application as AWT application before initializing
 - JavaFX application. JavaFX does not support dock-icon-less application so we are
 - creating JavaFX application from AWT application so that we can achieve the desired
 - functionality.
 - */

public class AWTMain {

    public static void main(String[] args) {

        // This is awt property which enables dock-icon-less
        // applications
        System.setProperty("apple.awt.UIElement", "true");
        java.awt.Toolkit.getDefaultToolkit();

        // This is a call to JavaFX application main method.
        // From now on we are transferring control to FX application.
        FXMain.main(args);
    }
}
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Thanks Erel. I will give it a try.

I personally have no issue with the extra icon in Dock however Apple requires it to not be there to be accepted on the Mac Store so this is my challenge :(

Any assistance you can lend on what requirements or switches to use to compile the main.java that may be required would be most helpful.

Thanks
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
I wonder and this is just out there. Can you make an option in b4j to choose if the *.java is to be saved or not saved at compile time? That would be Great! would be most helpful for cases like this to tweak the source java code . When I say save it it perhaps better to say not to regenerate the java but turn off the regeneration of the *.java files and just compile those existing java files to classes etc to achieve the jar file creation. I would be happy to test it to see if I get Mac Store acceptance as that is my second to last fix to gain acceptance straight from B4J -> B4JPackager11 ->platypus->MacOSApp.app->MacOSApp.pkg

I know you are making tremendous strives and I don't know how you manage your time you must have a time machine or something. But if you can find a way to facilitate that would be fantastic for Mac Store related submissions for B4J
 
Last edited:
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Not to complicate but just in case this capability exists already(or can be included more easily) in B4jBuilder, would the -Configuration switch allow logic to omit the .java code creation step and simply jump to compiling the already existing java coded files? or to ignore not being able to delete/overwrite (for eg main.java) and continue to the next step to compile to the main.class etc
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
I acknowledge my request may not be aligned currently to the evolution of B4J but it would ensure if my amendment achieves dock less icon for Java Coffee it would appease one of Apples Major requirements for mac Store. I would like to Request as a more tedious alternative as Erel suggested can any Java compilation/builder Guru assist me in defining the command line syntax/parameters to compile the .Java files created by B4J to create the resultant .class and Jar file I would be most grateful!
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Ok I decided to experiment as I await guidance from those more knowledgable in java than myself (probably everyone)

I'm attempting to build the untouched java code files created by B4J

I think I was able to create the classes as I got no errors and the classes were created. using javac -cp \jar\libraries\path\* *.java


I then used jar -cvf program.jar * to create the program.jar file but when I run B4JPackager11 it says:

B4X:
B4JPackager11 Version 1.15
Exe name: progwhizpdfviewer.exe
InputJar: E:\b4jProducts\ShowPDFinB4J\Objects\progwhizpdfviewer.jar
Running: E:\B4JPRO~1\B4JPAC~1\B4JPAC~1\Objects\temp\FindDosPath.exe
Running: C:\java11\jdk-11.0.1\bin\jar
main._appstart (java line: 114)
java.lang.RuntimeException: java.lang.IllegalStateException: No match found
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at anywheresoftware.b4a.keywords.Common$3.run(Common.java:1086)
    at anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(SimpleMessageLoop.java:30)
    at anywheresoftware.b4a.StandardBA.startMessageLoop(StandardBA.java:26)
    at anywheresoftware.b4a.keywords.Common.StartMessageLoop(Common.java:153)
    at com.progwhiz.b4jpackager.main._appstart(main.java:114)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
    at com.progwhiz.b4jpackager.main.main(main.java:28)
Caused by: java.lang.IllegalStateException: No match found
    at java.base/java.util.regex.Matcher.group(Matcher.java:645)
    at anywheresoftware.b4a.keywords.Regex$MatcherWrapper.Group(Regex.java:154)
    at com.progwhiz.b4jpackager.main$ResumableSub_FindPackageName.resume(main.java:527)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:136)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:85)
    ... 13 more

What do I need to do special with either javac or jar commands to satisfy finding the start of the main. Secondly when I use the jar -cvf command the current path contains the .class's, .java's and the required .jar's is this the correct assumption?
 
Last edited:
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Given the snippet of the main.java which is my main class or entry point?

B4X:
package com.progwhiz.pdfmacviewer;


import anywheresoftware.b4a.BA;

public class main extends javafx.application.Application{
public static main mostCurrent = new main();

public static BA ba;
static {
        ba = new  anywheresoftware.b4j.objects.FxBA("com.progwhiz.pdfmacviewer", "com.progwhiz.pdfmacviewer.main", null);
        ba.loadHtSubs(main.class);
        if (ba.getClass().getName().endsWith("ShellBA")) {
            
            ba.raiseEvent2(null, true, "SHELL", false);
            ba.raiseEvent2(null, true, "CREATE", true, "com.progwhiz.pdfmacviewer.main", ba);
        }
    }
    public static Class<?> getObject() {
        return main.class;
    }

 
    public static void main(String[] args) {
        launch(args);
    }
    public void start (javafx.stage.Stage stage) {
        try {
            if (!false)
                System.setProperty("apple.awt.UIElement", "true");
                System.setProperty("prism.lcdtext", "false");
            anywheresoftware.b4j.objects.FxBA.application = this;
            anywheresoftware.b4a.keywords.Common.setDensity(javafx.stage.Screen.getPrimary().getDpi());
            anywheresoftware.b4a.keywords.Common.LogDebug("Program started.");
            initializeProcessGlobals();
            anywheresoftware.b4j.objects.Form frm = new anywheresoftware.b4j.objects.Form();
            frm.initWithStage(ba, stage, 600, 400);
            ba.raiseEvent(null, "appstart", frm, (String[])getParameters().getRaw().toArray(new String[0]));
        } catch (Throwable t) {
            BA.printException(t, true);
            System.exit(1);
        }
    }
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
I see more now the effort involved but I will continue to try and hope as I progress I help those looking on who don't know what more experts do know.

I have overcome the running of B4JPackager11 with my produced jar file (which is still not yet built properly but is developing the jar inner file structure).

File structure to execute Javac and Jar commands successfully..

filstructure.png

After the .classes are created from the .java files then it is to execute the jar command. The syntax used jar -cfv program.jar -C Classes lib.
This jar command will embed(zip) the .class and all the files in /lib folder (mainly .jar's). The step after you have the create your own manifest file in ascii format. The structure is explained online. This default Manifest created is too basic and it misses alot of much needed information such as which is the main.class to launch and all libraries or classes required.. You apply this customised manifest as jar -cvfm program.jar manifest.txt.

Now this is where I reached. The jar is created it passes the build run on B4JPackager11 but it is not referencing or accessing all the necessary libraries or classes. The error I get when running the debug.bat from B4JPackager11 is:

buidlerror.png


Now in the Manifest there are 4 main attributes:

Package-Name
Class-Path
Main-Class

That is well publisized online but it only compiled and ran B4JPackager when I used a less known attribute called JavaFX-Application-Class. I gave both Main-Class and JavaFX-Application-Class the same name such as com.progwhiz.program.main So the questions is do I use one or the other or both as it is a Java App with JavaFx components a GUI App. The next question is do I use one or both to declare the library/class paths for Class-Path or JavaFX-Class-Path and if so which libraries are aligned to which.

So this is where I reached. I now discovered a Javafxpackager commandline tool and I'm thinking for this App which is using Javafx if I am required to use this packager instead of jar command line tool. So in the absence of any dialogue or guidance I will experiment further blindly. I may succeed in completing this task or surely succeed in a nervous breakdown.

so my questions at this point. Am I way off track in which case I will abort and take up knitting.

1) Using javac command line to compile the .class files from the .java files is correct?
2) Using jar command with the .classes and dependent jar files/libraries (and modified manifest) will achieve a properly created program.jar ?
3) If the latter two points is yes what attributes should I focus in the the Manifest and what libraries if not just the B4J libraries(jar's) to include in building the jar file
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Hi Erel

Im trying to reinernt the compile build process to have the ability to amend java launch code but this may not end well within the time frame required for b4j to comply one of apple's new requirements. So I have a feature request that would be more feasible and hopefully aligned to b4j capability evolution..

How about you add a new header in the code dialigues to show the first major block of the main.java to facilitate minor amendments and possibly any variables to inherit values. What do you think?

Thanls for lending me your eyes
 
Upvote 0

Chris2

Active Member
Licensed User
Going back to the original issue of the java coffee icon appearing.......
It's a while since I used it, and I can't test now as I don't have access to a Mac, but I'm sure there was an option in Platypus which stopped this occuring.

Perhaps;
1. Set Interface to None, &/or
2.
Deselect Remain running after completion, &/or
3.
Select Run in Background.

From https://sveinbjorn.org/files/manpages/PlatypusDocumentation.html;
Interface
None
Windowless application that provides no graphical feedback. All script output is redirected to STDERR.

Special Options
Runs in background: If selected, the application registers itself as a User Interface Element (LSUIElement) and will not appear in the Dock when launched.
Remain running after completion: This option tells the application to remain open after the script has executed.
 
Last edited:
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Dear Chris2,

Sadly none of those options dealt with the icon in the dock nor the menu bar showing 'Java' logo. I wished they did but those options only dealt with if a dialog appeared separate from the App etc not the docking or menu bar at the top of the screen.

Dear Erel,

Thanks for responding, if anyone can find a solution I know you can. I will endeavour to explain the issue as clear as I can for your analysis.

The App issue is stated here:

s5.png


The first two conflicts is easily resolved via the store metadata. The 3rd and 4th issues is the one's I'm highlighting for your kind brain storming.

In summary when we use the B4JPackager11 it works well and creates the stand alone file structure and executable. This executable works well and we have to package together as an .App and I chose to use platypus. This works nicely. I will show below what happens in each instance when you execute either the command.run right out of B4Japckager11 or the program.app via platypus.

s1.jpg


Now the next image will show the issue stated by apple where the program bundle name on the app store differs with the name in the menu bar as well as the logo of course.

s2.jpg


The next image shows the app launched as a program.app after platypus.
s3.jpg


The MenuBar and Dock icon are correct but the java doc and menu bar still remains in addition to same and apple see's this as a conflict in the naming and presence. When I researched it online that's when I saw the issue being resolved to hide the Java Dock presence and also the Java Menu Bar item. The command to be used and executed just prior or that start of the javafx are:

System.setProperty("apple.awt.UIElement", "true");
System.setProperty("apple.awt.headless", "true")
System.setProperty("java.awt.headless", "true")

These if executed in the main.java at the start of the javafx routine or just in calling same they said will do the trick to achieve dockless presnce fo javax icon in the dock and menu bar.

My humble thoughts is if we can include a new header block in B4J IDE showing the main.java top block code (you may represent said block with variable names to reflect the dynamic elements of the code to maintain the high standard set by you and your team) where we can insert said code we can test the theory and if it works and I'm sure it would with your guidance we would have finally reached the status of B4j as a tool to submit to Mac Store successfully. For this major exception as all other submission issues are not dependent on B4J as B4J is compliant in all other aspects of their submission process.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can set these properties before the JVM is created. Start with a simple test and run the jar from the command line and set the properties like this:
B4X:
java -Dapple.awt.UIElement=true -Dapple.awt.headless=true -Djava.awt.headless=true -jar YourJar.jar

If it works then it will be simple to set them with B4JPackager 11.
 
Upvote 0

Markos

Active Member
Licensed User
Longtime User
I wasn't sure that would work pre placing in an .App package as the only entity would then be the jar instance and to remove itself may not be feasible.

To successfully run the Java11 Jar I had to do the following:
java -Dapple.awt.UIElement=true -p /javafx_path/lib --add-modules javafxcontrol,javafx.fxml,javafx.media,javafx.swing -jar program.jar

And as I suspected the java icon was docked. I would like to try what is required to insert these commands in the B4J pre invoking the App start not using: SetSystemProperty("apple.awt.UIElement", "true") as that is executed after javafx is already instantiated or loaded I suspect.

Whilst you kindly consider what other option is feasible may I ask one huge favour. If it is not asking to reveal any secrets and I totally understand if it is, can you guide or provide a hint on what is needed to build the jar using the .Class files produced from the .java files produced by B4J? It will be soooo educational and may help me own the responsibility for this effort.

Thanks for the help thus far and possibly workable solution if time permits per your numerous efforts
 
Last edited:
Upvote 0

Markos

Active Member
Licensed User
Longtime User
Perhaps if this is more efficient. Can you create a program.jar based on javafx with the properties set prior to loading the javafx components/libraries:
1) one jar only using this property set
System.setProperty("apple.awt.UIElement", "true");

2) and the other with all 3 properties set
System.setProperty("apple.awt.UIElement", "true");
System.setProperty("apple.awt.headless", "true")
System.setProperty("java.awt.headless", "true")

I will then generate an .App package using B4JPackager11 and Platypus for each and test. This is an alternative to quickly test if this approach will achieve the desired result and if works can then deliberate what is the best way forward. Just a thought to find a most considerate use of your time
 
Upvote 0
Status
Not open for further replies.
Top