├── .gitattributes
├── .github
└── workflows
│ ├── maven-build-installer-macos.yml
│ ├── maven-build-installer-unix.yml
│ ├── maven-build-installer-windows.yml
│ └── maven-package.yml
├── .gitignore
├── LICENSE
├── README.md
├── app-icon.icns
├── app-icon.ico
├── app-icon.png
├── docs
├── java-15-jpackage.md
├── qna.md
└── sample-run.md
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── changenode
│ │ ├── BaseApplication.java
│ │ ├── BaseForm.form
│ │ ├── BaseForm.java
│ │ ├── Log.java
│ │ ├── Plugin.java
│ │ └── plugin
│ │ ├── DarkMode.java
│ │ ├── DesktopHandlers.java
│ │ ├── DesktopIntegration.java
│ │ ├── FileDrop.java
│ │ ├── HelloWorld.java
│ │ ├── LogFile.java
│ │ └── StandardMenus.java
└── resources
│ └── hello.txt
└── packaging
├── add-launch-to-msi.js
├── linux-jpackage.txt
├── mac-jpackage.txt
└── win-jpackage.txt
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/maven-build-installer-macos.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Build macOS Installer
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: macos-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up JDK 16
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: 16
23 | - name: Cache Maven packages
24 | uses: actions/cache@v2
25 | with:
26 | path: ~/.m2
27 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
28 | restore-keys: ${{ runner.os }}-m2
29 | - name: Build with Maven
30 | run: mvn -B clean install --file pom.xml
31 | - name: Update Automatic Release
32 | uses: marvinpinto/action-automatic-releases@latest
33 | with:
34 | repo_token: "${{ secrets.GITHUB_TOKEN}}"
35 | automatic_release_tag: "macOS-latest"
36 | prerelease: true
37 | title: "macOS Development Build"
38 | files: ./target/*.dmg
39 |
--------------------------------------------------------------------------------
/.github/workflows/maven-build-installer-unix.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Build Unix Installer
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Set up JDK 16
19 | uses: actions/setup-java@v1
20 | with:
21 | java-version: 16
22 | - name: Cache Maven packages
23 | uses: actions/cache@v2
24 | with:
25 | path: ~/.m2
26 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
27 | restore-keys: ${{ runner.os }}-m2
28 | - name: Build with Maven
29 | run: mvn -B clean install --file pom.xml
30 | - name: Update Automatic Release
31 | uses: marvinpinto/action-automatic-releases@latest
32 | with:
33 | repo_token: "${{ secrets.GITHUB_TOKEN}}"
34 | automatic_release_tag: "Ubuntu-latest"
35 | prerelease: true
36 | title: "Ubuntu Development Build"
37 | files: ./target/*.deb
38 |
--------------------------------------------------------------------------------
/.github/workflows/maven-build-installer-windows.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Build Windows Installer
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 | runs-on: windows-latest
15 | steps:
16 | - name: Download Wix
17 | uses: i3h/download-release-asset@v1
18 | with:
19 | owner: wixtoolset
20 | repo: wix3
21 | tag: wix3112rtm
22 | file: wix311-binaries.zip
23 | - name: Decompress Wix
24 | uses: DuckSoft/extract-7z-action@v1.0
25 | with:
26 | pathSource: wix311-binaries.zip
27 | pathTarget: ./target/wix
28 | - name: Add Wix to Path
29 | run: echo "$HOME/target/wix" >> $GITHUB_PATH
30 | - uses: actions/checkout@v2
31 | - name: Set up JDK 16
32 | uses: actions/setup-java@v1
33 | with:
34 | java-version: 16
35 | - name: Cache Maven packages
36 | uses: actions/cache@v2
37 | with:
38 | path: ~/.m2
39 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
40 | restore-keys: ${{ runner.os }}-m2
41 | - name: Build with Maven
42 | run: mvn -B clean install --file pom.xml
43 | - name: Update Automatic Release
44 | uses: marvinpinto/action-automatic-releases@latest
45 | with:
46 | repo_token: "${{ secrets.GITHUB_TOKEN}}"
47 | automatic_release_tag: "Windows-latest"
48 | prerelease: true
49 | title: "Windows Development Build"
50 | files: ./target/*.msi
51 |
--------------------------------------------------------------------------------
/.github/workflows/maven-package.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Maven Basic Package
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: macos-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up JDK 16
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: 16
23 | - name: Cache Maven packages
24 | uses: actions/cache@v2
25 | with:
26 | path: ~/.m2
27 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
28 | restore-keys: ${{ runner.os }}-m2
29 | - name: Build with Maven
30 | run: mvn -B clean package --file pom.xml
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.war
15 | *.nar
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | # Maven
25 | target/
26 |
27 | # IntelliJ project files
28 | *.iml
29 | *.iws
30 | *.ipr
31 | .idea/
32 |
33 | # OS
34 | .DS_Store
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaFX + Maven = Native Desktop Apps
2 |
3 | [Spring Boot](https://spring.io/projects/spring-boot) +
4 | [jpackage](https://docs.oracle.com/en/java/javase/15/docs/specs/man/jpackage.html) +
5 | [Maven](http://maven.apache.org) template project for generating native desktop applications.
6 |
7 | # Goal
8 |
9 | 1. Build nice, small cross-platform [Spring Boot](https://spring.io/projects/spring-boot) based desktop apps with native
10 | installers
11 | - Apx 30-40mb .dmg, .msi and .deb installers - check out the example builds in
12 | [releases](https://github.com/wiverson/desktop-spring-boot/releases).
13 | 2. Just use Maven - no shell scripts required.
14 | - Use standard Maven dependency system to manage dependencies
15 | 3.
16 |
17 | Generate [macOS (.dmg), Windows (.msi) and Unix (e.g. deb/rpm)](https://github.com/wiverson/maven-jpackage-template/releases)
18 | installers/packages automatically
19 | with [GitHub Actions](https://github.com/wiverson/maven-jpackage-template/tree/main/.github/workflows)
20 |
21 | In many ways this project provides a Java developer with tooling similar to Electron
22 | or [Neutralino.js](https://neutralino.js.org)
23 |
24 | ## Overview
25 |
26 | This template uses a [Maven plugin](https://github.com/wiverson/jtoolprovider-plugin) to generate a custom JVM and
27 | installer package for a Spring Boot application run as a desktop app. Conceptually this is similar to Electron
28 |
29 | The basic requirements are just Java 16 and Maven. [Java 15 will work](docs/java-15-jpackage.md), although it requires a
30 | bit of setup.
31 |
32 | - On macOS XCode is required.
33 | - On Windows the free [WiX Toolset](https://wixtoolset.org/) is required.
34 |
35 | The project includes [GitHub Actions](https://github.com/wiverson/maven-jpackage-template/tree/main/.github/workflows)
36 | which automatically generate macOS, Windows, and Linux installers.
37 |
38 | The generated installers come in at around 30-40mb. The example source in the project includes demonstrations of several
39 | native desktop features - for example, drag-and-drop from the Finder/Explorer, as well as a few macOS Dock integration
40 | examples. Removing the code and the demonstration dependendencies gets a "Hello World" build size closer to 30mb than
41 | 40mb.
42 |
43 | ## Key Features
44 |
45 | Here are few cool things in this template:
46 |
47 | - Only uses Java and Maven. No shell scripts required.
48 | - Includes sample [GitHub Actions](https://github.com/wiverson/maven-jpackage-template/tree/main/.github/workflows) to
49 | build macOS, Windows and Linux installers
50 | - Demonstrates setting the application icon
51 | - Builds a .dmg on macOS, .msi on Windows, and .deb on Linux
52 | - Bundles the JavaFX SDK & modules to simplify getting started.
53 | - Template includes several examples of JavaFX / native desktop integration
54 | - Drag & drop with Finder / Explorer
55 | - Change the Dock icon dynamically on macOS
56 | - Menu on the top for macOS, in the window itself on Windows
57 | - Request user attention (bouncing dock icon) on macOS
58 |
59 | Once you get started, you might find these lists of tutorials, tools, libraries for
60 | [JavaFX](https://gist.github.com/wiverson/6c7f49819016cece906f0e8cea195ea2)
61 | and general [Java desktop integration](https://gist.github.com/wiverson/e9dfd73ca9a9a222b2d0a3d68ae3f129) helpful.
62 |
63 | # Usage
64 |
65 | Once everything is installed (see below) it's really easy to use:
66 |
67 | To generate an installer, just run...
68 |
69 | `mvn clean install`
70 |
71 | To do everything up until the actual installer generation (including generating the custom JVM)...
72 |
73 | `mvn clean package`
74 |
75 | # Installation
76 |
77 | 1. Install [OpenJDK Java 16](https://adoptopenjdk.net/) or
78 | [Oracle Java 16](https://www.oracle.com/java/technologies/javase-downloads.html).
79 | - Verify by opening a fresh Terminal/Command Prompt and typing `java --version`.
80 | 2. Install [Apache Maven 3.6.3](http://maven.apache.org/install.html) or later and make sure it's on your path.
81 | - Verify this by opening a fresh Terminal/Command Prompt and typing `mvn --version`.
82 | 3. macOS: verify XCode is installed and needed agreements accepted.
83 | - Launch XCode and accept the license, or verify in Terminal with the command `sudo xcodebuild -license`.
84 | 5. Windows: install [Wix 3 binaries](https://github.com/wixtoolset/wix3/releases/).
85 | - Installing Wix via the installer should be sufficient for jpackage to find it.
86 | 3. Clone/download this project.
87 | 6. Final step: run `mvn clean install` from the root of the project to generate the `target\TestApp.dmg`
88 | or `target\TestApp.msi` (installer).
89 | - Note that the actual generated installer will include a version number in the file name
90 | - For reference, here is a complete run log for [a successful run](docs/sample-run.md).
91 |
92 | Because these builds use stripped down JVM images, the
93 | [generated installers are in the 30-40mb range](https://github.com/wiverson/maven-jpackage-template/releases).
94 |
95 | # Sponsor
96 |
97 | This project is sponsored by [ChangeNode.com](https://changenode.com/) - if you would like to add easy automatic
98 | updates, crash reporting, analytics, etc. to your Java/JavaFX desktop application, go check it out... and be sure to
99 | subscribe for more information about desktop Java development.
100 |
101 | # Help
102 |
103 | Problems? Make sure everything is installed and working right!
104 |
105 | - Compiler not recognizing the --release option? Probably on an old JDK.
106 | - Can't find jdeps? Probably on an old JDK.
107 | - Can't find jpackage? Probably haven't set up your system
108 | to [allow Java 15 to enable preview packages]((docs/java-15-jpackage.md)).
109 | - Unrecognized option: --add-modules jdk.incubator.jpackage
110 | - Could be a left-over MAVEN_OPTS setting when you switched from Java 15 to Java 16
111 | - If you are still on Java 15, you may not have
112 | [MAVEN_OPTS set correctly](https://github.com/wiverson/maven-jpackage-template/issues/2).
113 |
114 | If you need consulting support, feel free to reach out to [ChangeNode.com](https://changenode.com/).
115 |
116 | # Q&A
117 |
118 | If you are using the template, browsing the [Q&A](docs/qna.md) is highly recommended.
119 |
--------------------------------------------------------------------------------
/app-icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wiverson/desktop-spring-boot/32ef03da527457aacd64f4dce6649a0330e43ba0/app-icon.icns
--------------------------------------------------------------------------------
/app-icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wiverson/desktop-spring-boot/32ef03da527457aacd64f4dce6649a0330e43ba0/app-icon.ico
--------------------------------------------------------------------------------
/app-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wiverson/desktop-spring-boot/32ef03da527457aacd64f4dce6649a0330e43ba0/app-icon.png
--------------------------------------------------------------------------------
/docs/java-15-jpackage.md:
--------------------------------------------------------------------------------
1 | # Java 15 jpackage Configuration
2 |
3 | The [Java 15 branch](https://github.com/wiverson/maven-jpackage-template/tree/java-15) of this template is available,
4 | but no future updates are expected. You are strongly encouraged to move to Java 16, where jpackage is fully integrated
5 | into the JDK.
6 |
7 | In Java 15, the jpackage tool is only available as an incubator project. This means that you have to pass a special flag
8 | to the JVM to enable it. This project relies on [jtoolprovider-plugin](https://github.com/wiverson/jtoolprovider-plugin)
9 | to perform key build steps. To generate the actual installers, the jpackage tool must be available to the ToolProvider
10 | API. Adding a `MAVEN_OPTS` environment variable is the solution.
11 |
12 | ## macOS & Linux
13 |
14 | On macOS and Linux this can be done by adding to the following line to the `~/.zshrc` file (or a similar file on Linux,
15 | depending on your preferred shell).
16 |
17 | `export MAVEN_OPTS="--add-modules jdk.incubator.jpackage"`
18 |
19 | ## Windows
20 |
21 | Current versions of Windows 10 have a nice UI for adding an environment variable. You can find it in the modern control
22 | panel via search - just start a search for "env" and that should bring up the appropriate control panel. Note that on
23 | Windows, you don't need the quote marks - here's a
24 | [screenshot illustrating the proper configuration for a Windows 10 environment](https://github.com/wiverson/maven-jpackage-template/issues/2)
25 | .
26 |
27 | ## IntelliJ Maven Options Bug
28 |
29 | Unfortunately, as of this writing adding this entry to the IntelliJ options for Maven (either in the IntelliJ Maven JVM
30 | importer UI or via `project-directory/.mvn/jvm.config`) will break the Maven sync. This bug is tracked by JetBrains as
31 | [IDEA-246963](https://youtrack.jetbrains.com/issue/IDEA-246963). There is a `.mvn/Xjvm.config file` in this project -
32 | once the bug is fixed, or if you use a different editor, just try renaming that file to `jvm.config`.
33 |
34 | ## Summary
35 |
36 | So, to summarize: if you are on Java 15 you'll have to go through extra hoops to get Maven to work, and you'll likely
37 | run into compatibility issues due to a bug in IntelliJ. Or, just update to Java 16 and call it a day.
38 |
--------------------------------------------------------------------------------
/docs/qna.md:
--------------------------------------------------------------------------------
1 | # Q&A
2 |
3 | ### Q: Can you give me a few more details about how this works?
4 |
5 | A: Maven plugins are used to copy all the project dependencies into a folder, generate a slimmed-down JVM, and then
6 | generate a platform-specific installer.
7 | The [pom.xml](https://github.com/wiverson/maven-jpackage-template/blob/main/pom.xml)
8 | is heavily commented!
9 |
10 | ### Q: What are all the folders in the target directory?
11 |
12 | A: Here are the folders unique to this project:
13 |
14 | - `dependency` - all of the jar files declared by your Maven project, including the jar containing your code
15 | - `installer-work` - the platform specific working files generated by jpackage.
16 | - [Wix Toolset](https://wixtoolset.org) files on Windows
17 | - [Script Editor](https://support.apple.com/guide/script-editor/welcome/mac) on macOS.
18 | - `jvm-image` - Platform-specific, trimmed down JVM.
19 | - `packaging` - Platform-specific commands, filtered by Maven and fed to jpackage.
20 |
21 | Standard Maven folders:
22 |
23 | - `classes` - generated by the javac compiler, contains your compiled code.
24 | - `generated-sources` - side-effect of the javac compiler
25 | - `maven-archiver` - side-effect of Maven execution.
26 | - `maven-status` - side-effect of Maven compiler
27 |
28 | ### Q: Any Tips for Windows?
29 |
30 | A: First, make sure you **set a custom Windows installer UUID for your project**, as described in
31 | the [pom.xml](https://github.com/wiverson/maven-jpackage-template/blob/main/pom.xml)!
32 |
33 | This UUID is used to uniquely identify the app as YOUR app by the Windows installer system, and is critical for allowing
34 | users to seamlessly upgrade. You can quickly [grab a UUID of your own](https://www.uuidgenerator.net/) and pop that
35 | value in instead. By default jpackage will generate a UUID automatically, but this automatic UUID is easily regenerated
36 | with minor changes to your application, breaking the Windows installer upgrade chain.
37 |
38 | The [Windows GitHub workflow](https://github.com/wiverson/maven-jpackage-template/blob/main/.github/workflows/maven-build-installer-windows.yml)
39 | for this project downloads the Wix Installer toolkit and adds it to the path to automatically build the Windows
40 | installer. On your local dev machine just install [WiX Toolset](https://wixtoolset.org/)
41 | locally instead - it'll be a lot faster.
42 |
43 | ### Q: I'm getting errors when I'm trying to use javafx.web?
44 |
45 | A: GitHub won't allow cloning a template if the source has files over 10mb in size. The javafx.web components basically
46 | bundle a full native web browser under the covers. As of JavaFX 15 the javafx.web.jmod is roughly 25mb in size. If you
47 | need it, you can [download it](https://gluonhq.com/products/javafx/) and install it in the JavaFX projects in your local
48 | project.
49 |
50 | If you are delivering a project that essentially amounts to a Java web application bundled as a web application, instead
51 | of bundling JavaFX and a WebKit browser, I would suggest creating a small preferences UI using Swing and
52 | the [System Tray API](https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html). With a nice modern look and
53 | feel such as [FlatLaf](https://www.formdev.com/flatlaf/), you can create a very nice preferences panel and then use the
54 | standard Java [Desktop API](https://docs.oracle.com/javase/9/docs/api/java/awt/Desktop.html) to just launch the user's
55 | browser to the local URL.
56 |
57 | If you drop me a note that this is something you are interested in, I may go ahead and create a template for this... :)
58 |
59 | ### Q: Tell me a bit about the Linux version?
60 |
61 | A: The current GitHub Workflow for the Linux build runs on a GitHub Ubuntu instance, and by default it generates a
62 | amd64.deb file. jpackage supports other distribution formats, including rpm, so if you want a different packaging format
63 | you can tweak the
64 | [GitHub Action for the Ubuntu build](https://github.com/wiverson/maven-jpackage-template/blob/main/.github/workflows/maven-build-installer-unix.yml)
65 | and
66 | the [jpackage command for Unix](https://github.com/wiverson/maven-jpackage-template/blob/main/src/packaging/unix-jpackage.txt)
67 | to generate whatever you need. As long as you can find the right combination of configuration flags for
68 | [jpackage](https://docs.oracle.com/en/java/javase/15/docs/specs/man/jpackage.html) and can set up the GitHub Actions
69 | runner to match, you can generate whatever packaging you might need. If you need, you could set up several combinations
70 | of Maven profile and GitHub Action to generate as many different builds as you wish to support. For example, you could
71 | support generating macOS .dmg and .pkg files, Windows .msi and .exe, Linux .deb and .rpm in several different binary
72 | formats.
73 |
74 | ### Q: What about macOS Signing?
75 |
76 | A: You will likely need to add additional options to ship properly on macOS - most notably, you will want to sign and
77 | notarize your app for macOS to make everything work without end user warnings. Check out tools such
78 | as [Gon](https://github.com/nordcloud/gon)
79 | or [this command-line signing tutorial](https://blog.dgunia.de/2020/02/12/signed-macos-programs-with-java-14/).
80 |
81 | ### Q: Can I generate macOS installers on Windows, or Windows installers on macOS? Or macOS/Windows on Linux?
82 |
83 | A: [No](https://openjdk.java.net/jeps/392), but this project uses GitHub workflows to generate
84 | [macOS](https://github.com/wiverson/maven-jpackage-template/blob/main/.github/workflows/maven-build-installer.yml)
85 | and
86 | [Windows](https://github.com/wiverson/maven-jpackage-template/blob/main/.github/workflows/maven-build-installer-windows.yml) (
87 | and Linux)
88 | installers automatically, regardless of your development platform. This means that (for example)
89 | you could do your dev work on Linux and rely on the GitHub Actions to generate macOS and Windows builds. If you need
90 | help, reach out to [ChangeNode.com](https://changenode.com/).
91 |
92 | You still should (of course) do platform specific testing on your apps, but that's a different topic.
93 |
94 | ### Q: Does this support auto-updating, crash reporting, or analytics?
95 |
96 | A: No... for that, you should check out [ChangeNode.com](https://changenode.com/)!
97 |
98 | ### Q: I'd rather use shell scripts.
99 |
100 | A: Ok. Check out [JPackageScriptFX](https://github.com/dlemmermann/JPackageScriptFX) - the original shell scripts used
101 | as a reference when I initially started work on this project.
102 |
103 | ### Q: I didn't realize JavaFX was so cool - any pointers?
104 |
105 | Sure - here's
106 | my [personal list of cool JavaFX resources](https://gist.github.com/wiverson/6c7f49819016cece906f0e8cea195ea2), which
107 | includes links to a few other big lists of resources.
108 |
109 | ### Q: Any Maven tips?
110 |
111 | If you are not familiar with the standard Maven build lifecycle, you are highly encouraged to review the documentation
112 | ["Introduction to the Build Lifecycle"](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
113 | to understand how Maven builds work.
114 |
115 | The project also uses os-activated, platform-specific
116 | [profiles](https://maven.apache.org/guides/introduction/introduction-to-profiles.html) for configuration - really cool
117 | for setting up platform-specific stuff.
118 |
119 | ### Q: Wait, didn't this project use to try to completely modularize the application first?
120 |
121 | A: Correct.
122 |
123 | There were two previous versions of this template, and both strategies were discarded as impractical in the real world.
124 |
125 | The first approach was to **try to create a shaded jar** (a single jar containing all of the project dependencies) and
126 | then use jdeps to create a module-info.java and add it to the shaded jar. This failed to account for things like
127 | multi-release jars and jars with service declarations. While it worked for trivial applications, it fell apart with more
128 | complex real world usage. In particular, attempting to integrate Spring Boot into the application caused many issues to
129 | appear.
130 |
131 | The second attempt took a more sophisticated approach - **using jdeps to automatically modularize all of the project
132 | dependencies.**
133 | A new [`collect-modules` goal](https://github.com/wiverson/jtoolprovider-plugin/blob/main/collect-modules-doc.md)
134 | was added. In brief, the plugin would walk through the entire Maven dependency tree and sort all of the declared
135 | dependencies into folders. The dependencies that already were modularized (both basic and multi-release jars) went into
136 | one folder, and ordinary non-modularized jars went into another. The plugin would then attempt to use jdeps to
137 | automatically generate module-info.java and add the compiled module-info.classes into each jar.
138 |
139 | Unfortunately, this also failed. There were numerous errors, such a circular references between libraries (e.g. slf4j
140 | and logback). Some jars would only work when jdeps generated open module-info.java files, and others would only work
141 | when jdeps generated module-info.java files with package level exports. Many, many jars would have large numbers of
142 | packages exposed, which mean that the resulting module-info.java files contained many, many entries. The error messages
143 | and the resolution for these messages were very, very confusing. The terminology around modules is unfortunately very
144 | inaccessible to a typical Java developer - for example, a "static" declaration in a Java module-info.java is used to
145 | denote a concept similar to the Maven notion of "provided" - but unfortunately jdeps fails to run if a needed module is
146 | declared as a transitive reference. Even if it's optional.
147 |
148 | In the end, even with the plugin, the error messages and the resolution of those messages is just simply not something a
149 | typical Java developer can be expected to understand or fix.
150 |
151 | Which brings us back to this project. The end result is effective the same - just change
152 | the `