├── .gitignore ├── LICENSE ├── README.en.md ├── README.md ├── cli-normal ├── native-image-agent.bat ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── mueeee │ │ └── clinormal │ │ └── CliNormalApp.java │ └── resources │ └── app.properties ├── cli-picocli ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── mueeee │ │ └── clipicocli │ │ └── CliPicocliApp.java │ └── resources │ └── app.properties ├── desktop-javafx ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── mueeee │ │ │ └── desktopjavafx │ │ │ ├── App.java │ │ │ ├── DesktopJavaFxApp.java │ │ │ ├── conf │ │ │ └── AppConfig.java │ │ │ └── ctrl │ │ │ └── MainCtrl.java │ └── resources │ │ └── com │ │ └── mueeee │ │ └── desktopjavafx │ │ ├── app.properties │ │ ├── css │ │ └── Main.css │ │ ├── fxml │ │ └── Main.fxml │ │ └── icon │ │ ├── icon.ico │ │ └── icon.png │ └── windows │ └── assets │ └── icon.ico ├── pom.xml ├── web-jlhttp ├── native-image-agent.bat ├── pom.xml └── src │ └── main │ ├── java │ ├── com │ │ └── mueeee │ │ │ └── webjlhttp │ │ │ └── WebJLHttpApp.java │ └── net │ │ └── freeutils │ │ └── httpserver │ │ └── HTTPServer.java │ └── resources │ └── application.properties ├── web-nanohttpd ├── native-image-agent.bat ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── mueeee │ │ └── webnanohttpd │ │ └── WebNanoHttpdApp.java │ └── resources │ └── application.properties ├── web-springboot ├── README.md ├── native-image-agent.bat ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── mueeee │ │ └── webspringboot │ │ ├── AppRunner.java │ │ ├── CorsConfig.java │ │ ├── MainController.java │ │ └── WebSpringBootApp.java │ └── resources │ ├── application.properties │ ├── static │ └── image │ │ ├── graalvm-logo.png │ │ └── spring-logo.png │ └── templates │ └── index.html └── web-springboot3 ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── native-image-agent.bat ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── mueeee │ │ └── webspringboot3 │ │ ├── AppRunner.java │ │ ├── CorsConfig.java │ │ ├── MainController.java │ │ └── WebSpringboot3App.java └── resources │ ├── application.properties │ ├── static │ └── image │ │ ├── graalvm-logo.png │ │ └── spring-logo.png │ └── templates │ └── index.html └── test └── java └── com └── mueeee └── webspringboot3 └── WebSpringboot3ApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | 35 | # native-image run agent 36 | **/META-INF/native-image/ -------------------------------------------------------------------------------- /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.en.md: -------------------------------------------------------------------------------- 1 | # java-graalvm-start 2 | 3 | - [Gitee](https://gitee.com/westinyang/java-graalvm-start) 4 | - [Gtihub](https://github.com/westinyang/java-graalvm-start) 5 | 6 | [中文文档](README.md) 7 | 8 | [Open Source Development License](https://www.jetbrains.com/community/opensource/#support?from=https://github.com/westinyang/java-graalvm-start) Product Subscriptions provided by JetBrains 9 | 10 | ![JetBrains logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg) 11 | 12 | ## Description 13 | 14 | Graal VM best practice, use Java to develop CLI, Desktop (Java FX), Web (Spring Boot) projects, and use native-image technology to statically compile Java code into independent executable files (native images). 15 | 16 | > Graal VM makes Java powerful again, using native-image to compile the program into an executable file of the target platform, and run directly without jvm, the startup speed is very fast, and the memory load is also very low. 17 | 18 | ## Module overview 19 | 20 | > To experience the executable file I have compiled (Windows, Linux, Mac), [click here to download](https://gitee.com/westinyang/java-graalvm-start/releases/v1.0). 21 | > 22 | > The following performance test results are tested on my native Windows. The test results are related to the machine configuration, especially the time-consuming compilation of `native-image`. 23 | 24 | | ↓Tag \ Module→ | [cli-normal](cli-normal) | [desktop-javafx](desktop-javafx) | [web-springboot](web-springboot) | 25 | | ----- | ----- | ----- | ----- | 26 | | Module desc | Command line app (no framework) | Desktop app (JavaFx) | Web app (SpringBoot) | 27 | | JDK | 11 or 17 | 11 or 17 | 11 or 17 | 28 | | GraalVM | CE-21.3.0 | CE-21.3.0 | CE-21.3.0 | 29 | | Maven Plugin | native-maven-plugin | gluonfx-maven-plugin | spring-native | 30 | | Time-consuming to start (jvm) | 0.713s | 2.555s | 1.793s | 31 | | **Time-consuming to start (native-image)** | **0.047s** | **0.665s** | **0.216s** | 32 | | Memory load(jvm) | 38.8m | 309.3m | 440.5m | 33 | | **Memory load(native-image)** | **3.1m** | **60.4m** | **70.2m** | 34 | | Time-consuming to start (native-image) | 24.786s | 93.455s | 99.434s | 35 | | Executable file size (7z compression) | 8.03m (7z : 1.68m) | 62.7m (7z : 13.1m) | 66.5m (7z : 13.9m) | 36 | 37 | **New module** 38 | 39 | > Brief introduction of new modules and basic test data 40 | 41 | - [web-jlhttp](web-jlhttp) 42 | - Embedded HTTP Server implemented with only 3000 lines of Java code, sometimes we just want to write one or two simple interfaces for packaging and publishing. Using frameworks such as Spring is really a fuss. 43 | - jarfile:`52k`,Executable file size:`12.9m`, 7z:`2.9m` 44 | - [web-nanohttpd](web-nanohttpd) 45 | - Another lightweight and well-designed embedded HTTP Server implementation. The library is commonly used for Android application development, but it can be used normally with Graal VM here. 46 | - jarfile:`54k`,Executable file size:`12.8m`, 7z:`2.9m` 47 | - [cli-picocli](cli-picocli) 48 | - Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. 49 | - jarfile: `676k`,Executable file size:`18.2m`,7z:`4.0m` 50 | - [web-springboot3](web-springboot3) 51 | - Spring Boot 3.0 has been officially released, supporting Graalvm Native Images, replacing experimental Spring Native projects. 52 | - jarfile: `19.2m`,Executable file size:`72.0m`,7z:`16.4m` 53 | 54 | ## Plugin changes 55 | 56 | - **2021-03-05** GraalVM-21.0.0.2 (Java 8 or Java 11) `First commit` 57 | - org.graalvm.nativeimage/native-image-maven-plugin:21.0.0.2 `cli` 58 | - com.gluonhq/client-maven-plugin:0.1.38 `javafx 15.0.1` 59 | - org.springframework.experimental/spring-graalvm-native:0.8.5 `springboot 2.4.3` 60 | - **2021-12-10** GraalVM-21.3.0 (Java 11 or Java 17) 61 | - [org.graalvm.buildtools/native-maven-plugin:0.9.8](https://graalvm.github.io/native-build-tools/latest/index.html) `cli` 62 | - [com.gluonhq/gluonfx-maven-plugin:1.0.10](https://docs.gluonhq.com/#_gluonfx_plugin_for_maven) `javafx 17.0.1` 63 | - [org.springframework.experimental/spring-native:0.11.0](https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/index.html) `springboot 2.6.1` 64 | 65 | ## Development environment 66 | 67 | > The following is the development environment of my machine. In theory, windows, linux and mac are all supported (note that the dependencies of GraalVM SDK and native-image of different platforms are different). 68 | 69 | - Windows 10 (CPU: i7-7700, RAM: 16G) 70 | - IntelliJ IDEA 2020 71 | - graalvm-ce-java11-21.3.0 72 | - Visual Studio 2019 73 | 74 | ## Environment configuration (Windows) 75 | 76 | **Graal VM** 77 | - [Download Graal VM SDK](https://github.com/graalvm/graalvm-ce-builds/releases) 78 | - Set GraalVM environment variables (note that JAVA_HOME also points to GRAALVM_HOME): 79 | ``` bat 80 | GRAALVM_HOME = C:\path\to\graalvm-ce-java11-21.3.0 81 | JAVA_HOME = %GRAALVM_HOME% 82 | PATH += %GRAALVM_HOME%\bin 83 | ``` 84 | - Verify the environment `java -version` 85 | ``` 86 | C:\Users\Administrator>java -version 87 | openjdk version "11.0.13" 2021-10-19 88 | OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05) 89 | OpenJDK 64-Bit Server VM GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05, mixed mode, sharing) 90 | ``` 91 | - Install native-image components 92 | ``` bat 93 | gu install native-image 94 | ``` 95 | - Verification component 96 | ``` bat 97 | gu list 98 | native-image --version 99 | ``` 100 | 101 | **MSVC (Visual Studio 2019)** 102 | 103 | > In addition to GraalVM, Microsoft Visual Studio 2019 is also required. The community version is enough, You can [download it from here](https://visualstudio.microsoft.com/downloads/) 104 | 105 | During the installation process, make sure to select at least the following individual components: 106 | 107 | - Choose the English Language Pack 108 | - C++/CLI support for v142 build tools (14.25 or later) 109 | - MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25 or later) 110 | - Windows Universal CRT SDK 111 | - Windows 10 SDK (10.0.19041.0 or later) 112 | 113 | > All build commands, be it with Maven or Gradle, must be executed in a Visual Studio 2019 Command Prompt called x64 Native Tools Command Prompt for VS 2019. A shortcut can be found in the "Start Menu", or you can search the application in the search box. Read the Microsoft documentation for more information. 114 | > 115 | > Alternatively, you can run `cmd.exe /k "\VC\Auxiliary\Build\vcvars64.bat` from any other terminal before you can start using the build commands. 116 | 117 | > **Recommend this ultimate solution: [Visual Studio 2019 configure MSVC environment variables, use the command line to compile](https://www.jianshu.com/p/7fab25165f4b),In this way, MSVC compilation tools can be used directly on any terminal.** 118 | > 119 | > Be sure to use this ultimate solution, otherwise it will become very troublesome in the build project. Every time before `mvn package`, you must execute `cmd.exe k "\VC\Auxiliary\ Build\vcvars64.bat`. 120 | 121 | ## Environment configuration(Linux/Mac) 122 | 123 | **Linux** 124 | 125 | Download Graal VM and configure environment variables. In addition to Graal VM, the following software packages are also required: 126 | 127 | - gcc version 6 or higher 128 | - ld version 2.26 or higher 129 | - Ubuntu 18 also needs to install the following libraries (I have tested it in the Linux subsystem): 130 | ```shell script 131 | sudo apt install pkg-config libgl-dev libglib2.0-dev libgtk-3-dev libpango1.0-dev libx11-dev libxtst-dev libasound2-dev libavcodec-dev libavformat-dev libavutil-dev 132 | ``` 133 | - Ubuntu 20 also needs to install the following libraries 134 | ```shell 135 | sudo apt install g++-multilib 136 | ``` 137 | - For other Linux distributions, please check which dependent libraries are missing for errors when packaging, and install them yourself. 138 | 139 | **Mac** 140 | 141 | - xcode-select --install 142 | 143 | For a more detailed description of different platform configurations and dependencies, please refer to: 144 | - [install-native-image](https://www.graalvm.org/reference-manual/native-image/#install-native-image) `Reference when building Java applications` 145 | - [gluon documentation](https://docs.gluonhq.com/#_platforms) `Reference when building JavaFx applications` 146 | 147 | > tips:Gluon is a contributor to the `OpenJFX` project and the `GraalVM` project. The company provides `client-maven-plugin` to encapsulate the related commands of `native-image`, which simplifies the packaging operation. 148 | 149 | ## Precautions 150 | 151 | - Through the above steps, you have configured the development environment. Another thing to note is that in IDEA development tools, when you need to set the JDK for the project, you should directly point to the bin directory under GraalVM, not other JDK directories, Otherwise an error may occur during compilation. 152 | 153 | ## Extended reading 154 | 155 | - GraalVM should not support cross-compilation, but you can use the Linux subsystem provided by Windows to compile the source code. 156 | 157 | ## Follow-up planning 158 | 159 | > For other implementations of these three applications, more modules may be added later. 160 | 161 | - cli-<A library that supports parsing args parameters> `For faster development of cli applications` 162 | - desktop-<Swing/AWT> `Other GUI implementations` 163 | - web-<Lightweight, containerless http-server library> `Other web implementations` 164 | 165 | ## Technology Exchange 166 | 167 | - Q Group: [707416319](https://qm.qq.com/cgi-bin/qm/qr?k=uSAXH8sKqQnF_cvDSF4T8IN7tSqabAJ3&jump_from=webapi) 168 | - About the author: [I'm westinyang](https://kaihongpai.feishu.cn/wiki/CqWLwJRadibxztkrIWZcogWxnXd) 169 | 170 | ## Reference 171 | 172 | - Official information 173 | - [Get Started with GraalVM](https://www.graalvm.org/docs/getting-started/) 174 | - [native-image documentation](https://www.graalvm.org/reference-manual/native-image/) 175 | - [JavaFX website](https://openjfx.io/) `Recommended reading` 176 | - [Spring Native for GraalVM documentation](https://repo.spring.io/milestone/org/springframework/experimental/spring-graalvm-native-docs/0.8.5/spring-graalvm-native-docs-0.8.5.zip!/reference/index.html) `Recommended reading` 177 | - Web articles 178 | - [How to evaluate the GraalVM project?](https://www.zhihu.com/question/274042223) `Recommended reading` 179 | - [Graal VM: Java in the age of microservices](https://www.zhihu.com/column/p/137836206) `Recommended reading` `Very comprehensive explanation` 180 | - [Generate native image for JavaFX application](https://zhuanlan.zhihu.com/p/103606559?utm_source=wechat_session) 181 | - [Use GraalVM under Windows to compile JavaFX applications into exe](https://www.cnblogs.com/dehai/p/14258391.html) 182 | - [Spring Boot as GraalVM Native Images](https://blog.codecentric.de/en/2020/05/spring-boot-graalvm/) `Recommended reading` 183 | - [Spring Boot GraalVM Native Image builds with the native-image-maven-plugin](https://blog.codecentric.de/en/2020/05/spring-boot-graalvm/) `Recommended reading` 184 | - [How to build native CLI applications written in Java with Graalvm and Picocli](https://www.infoq.cn/article/4RRJuxPRE80h7YsHZJtX) `推荐阅读` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # java-graalvm-start 2 | 3 | - [Gitee](https://gitee.com/westinyang/java-graalvm-start) 4 | - [Gtihub](https://github.com/westinyang/java-graalvm-start) 5 | 6 | [English document](README.en.md) 7 | 8 | 由 JetBrains 提供的 [开源开发许可证](https://www.jetbrains.com/community/opensource/#support?from=https://github.com/westinyang/java-graalvm-start) 产品订阅 9 | 10 | ![JetBrains logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg) 11 | 12 | ## 介绍 13 | 14 | GraalVM最佳实践,使用Java开发CLI、Desktop(JavaFX)、Web(SpringBoot)项目,并使用native-image技术把Java代码静态编译为独立可执行文件(本机映像)。 15 | 16 | > GraalVM让Java再次变得强大,使用native-image把程序编译为目标平台的可执行文件,脱离jvm直接运行,启动速度飞快,内存负载也很低。 17 | 18 | ## 模块概览 19 | 20 | > 体验我已经编译好的可执行文件(Windows、Linux、Mac),[点此下载](https://gitee.com/westinyang/java-graalvm-start/releases/v1.0)。 21 | > 22 | > 下面的性能测试结果是在我本机Windows上测试的,测试结果与机器配置有关,尤其是 `native-image` 编译耗时。 23 | 24 | | ↓标签 \ 模块→ | [cli-normal](cli-normal) | [desktop-javafx](desktop-javafx) | [web-springboot](web-springboot) | 25 | | ----- | ----- | ----- | ----- | 26 | | 模块描述 | 命令行应用(无框架) | 桌面应用(JavaFx) | Web应用(SpringBoot) | 27 | | JDK | 11 or 17 | 11 or 17 | 11 or 17 | 28 | | GraalVM | CE-21.3.0 | CE-21.3.0 | CE-21.3.0 | 29 | | Maven Plugin | native-maven-plugin | gluonfx-maven-plugin | spring-native | 30 | | 启动耗时(jvm) | 0.713s | 2.555s | 1.793s | 31 | | **启动耗时(native-image)** | **0.047s** | **0.665s** | **0.216s** | 32 | | 内存负载(jvm) | 38.8m | 309.3m | 440.5m | 33 | | **内存负载(native-image)** | **3.1m** | **60.4m** | **70.2m** | 34 | | 编译耗时(native-image) | 24.786s | 93.455s | 99.434s | 35 | | 可执行文件大小(7z压缩) | 8.03m (7z : 1.68m) | 62.7m (7z : 13.1m) | 66.5m (7z : 13.9m) | 36 | 37 | **新增模块** 38 | 39 | > 新增模块简单介绍和基本测试数据 40 | 41 | - [web-jlhttp](web-jlhttp) 42 | - 仅3000行Java代码实现的嵌入式HTTPServer,有些时候我们仅仅是想写一两个简单的接口打包发布,使用Spring等框架真的是觉得小题大做了。 43 | - jarfile:`52k`,可执行文件大小:`12.9m`, 7z:`2.9m` 44 | - [web-nanohttpd](web-nanohttpd) 45 | - 另一种轻量级且设计良好的嵌入式HTTPServer实现,该库常用于Android应用开发,不过在这里配合GraalVM一样能正常使用。 46 | - jarfile:`54k`,可执行文件大小:`12.8m`, 7z:`2.9m` 47 | - [cli-picocli](cli-picocli) 48 | - Picocli 是一个现代框架,用于轻松构建功能强大、用户友好、支持 GraalVM 的命令行应用程序。它支持颜色、自动补全、子命令等。 49 | - jarfile: `676k`,可执行文件大小:`18.2m`,7z:`4.0m` 50 | - [web-springboot3](web-springboot3) 51 | - Spring Boot 3.0 已正式发布,支持 GraalVM native images,取代实验性的 Spring Native 项目。 52 | - jarfile: `19.2m`,可执行文件大小:`72.0m`,7z:`16.4m` 53 | 54 | ## 插件变更 55 | 56 | - **2021-03-05** GraalVM-21.0.0.2 (Java 8 or Java 11) `首次提交` 57 | - org.graalvm.nativeimage/native-image-maven-plugin:21.0.0.2 `cli` 58 | - com.gluonhq/client-maven-plugin:0.1.38 `javafx 15.0.1` 59 | - org.springframework.experimental/spring-graalvm-native:0.8.5 `springboot 2.4.3` 60 | - **2021-12-10** GraalVM-21.3.0 (Java 11 or Java 17) 61 | - [org.graalvm.buildtools/native-maven-plugin:0.9.8](https://graalvm.github.io/native-build-tools/latest/index.html) `cli` 62 | - [com.gluonhq/gluonfx-maven-plugin:1.0.10](https://docs.gluonhq.com/#_gluonfx_plugin_for_maven) `javafx 17.0.1` 63 | - [org.springframework.experimental/spring-native:0.11.0](https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/index.html) `springboot 2.6.1` 64 | 65 | ## 开发环境 66 | 67 | > 以下是我本机的开发环境,理论上windows、linux、mac都是支持的(注意不同平台的 GraalVM SDK 和 native-image的依赖是不一样的)。 68 | 69 | - Windows 10 (CPU: i7-7700, RAM: 16G) 70 | - IntelliJ IDEA 2020 71 | - graalvm-ce-java11-21.3.0 72 | - Visual Studio 2019 73 | 74 | ## 环境配置(Windows) 75 | 76 | **Graal VM** 77 | - [下载 Graal VM SDK](https://github.com/graalvm/graalvm-ce-builds/releases) 78 | - 设置GraalVM环境变量(注意JAVA_HOME也要指向GRAALVM_HOME): 79 | ``` bat 80 | GRAALVM_HOME = C:\path\to\graalvm-ce-java11-21.3.0 81 | JAVA_HOME = %GRAALVM_HOME% 82 | PATH += %GRAALVM_HOME%\bin 83 | ``` 84 | - 验证环境 `java -version` 85 | ``` 86 | C:\Users\Administrator>java -version 87 | openjdk version "11.0.13" 2021-10-19 88 | OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05) 89 | OpenJDK 64-Bit Server VM GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05, mixed mode, sharing) 90 | ``` 91 | - 安装native-image组件 92 | ``` bat 93 | gu install native-image 94 | ``` 95 | - 验证组件 96 | ``` bat 97 | gu list 98 | native-image --version 99 | ``` 100 | 101 | **MSVC (Visual Studio 2019)** 102 | 103 | > 除了GraalVM,还需要Microsoft Visual Studio 2019。社区版就足够了,可以从[这里下载](https://visualstudio.microsoft.com/downloads/)。 104 | 105 | 在安装过程中,请确保至少选择以下各个组件: 106 | 107 | - 选择英语语言包 108 | - C++/CLI v142 构建工具(14.25或更高版本) 109 | - MSVC v142 - VS 2019 C++ x64/x86 构建工具(v14.25或更高版本) 110 | - Windows 通用 CRT SDK 111 | - Windows 10 SDK(10.0.19041.0或更高版本) 112 | 113 | > 所有构建命令(无论是Maven还是Gradle)都必须在名为的Visual Studio 2019命令提示符中执行 `x64 Native Tools Command Prompt for VS 2019`。快捷方式可以在“开始菜单”中找到,也可以在搜索框中搜索应用程序。 阅读Microsoft文档以获取更多信息。 114 | > 115 | > 另外,您可以执行 `cmd.exe /k "\VC\Auxiliary\Build\vcvars64.bat` 从任何其他终端运行,然后再开始使用构建命令。 116 | 117 | > **推荐这个终极方案:[Visual Studio 2019 配置 MSVC 环境变量,使用命令行编译](https://www.jianshu.com/p/7fab25165f4b),这样就可以在任何终端直接使用MSVC的编译工具。** 118 | > 119 | > 一定要使用这个终极方案,否则在接下来的项目构建中,将会变得很麻烦,每次 `mvn package` 之前都要先执行 `cmd.exe /k "\VC\Auxiliary\Build\vcvars64.bat` 。 120 | 121 | ## 环境配置(Linux/Mac) 122 | 123 | **Linux** 124 | 125 | 下载GraalVM,配置环境变量,除了GraalVM,还需要以下软件包: 126 | 127 | - gcc 6 或更高版本 128 | - ld 2.26 或更高版本 129 | - Ubuntu 18 还需要安装以下这些库(我在Linux子系统中已经测试通过): 130 | ```shell script 131 | sudo apt install pkg-config libgl-dev libglib2.0-dev libgtk-3-dev libpango1.0-dev libx11-dev libxtst-dev libasound2-dev libavcodec-dev libavformat-dev libavutil-dev 132 | ``` 133 | - Ubuntu 20 还需要安装以下这些库 134 | ```shell 135 | sudo apt install g++-multilib 136 | ``` 137 | - 其他Linux发行版,请在打包时查看错误都缺少哪些依赖库,自行安装。 138 | 139 | **Mac** 140 | 141 | - xcode-select --install 142 | 143 | 有关不同平台配置和依赖更详细的说明,请参考: 144 | - [install-native-image](https://www.graalvm.org/reference-manual/native-image/#install-native-image) `构建Java应用时参考` 145 | - [gluon documentation](https://docs.gluonhq.com/#_platforms) `构建JavaFx应用时参考` 146 | 147 | > tips:Gluon公司是 `OpenJFX` 项目和 `GraalVM` 项目的贡献者,该公司提供了 `client-maven-plugin ` 封装了 `native-image` 的相关命令,简化了打包操作。 148 | 149 | ## 注意事项 150 | 151 | - 通过上述步骤,你已经配置好了开发环境,还有一点需要注意的是,在IDEA开发工具中,你需要为项目设置JDK的时候应该直接指向GraalVM下的bin目录,而不是其他JDK的目录,否则在编译时可能会出现错误。 152 | 153 | ## 扩展阅读 154 | 155 | - GraalVM应该是不支持交叉编译的,不过可以利用Windows提供的Linux子系统来编译源码。 156 | 157 | ## 后续规划 158 | 159 | > 对于这三种应用的其他实现方式,后续可能会添加更多的模块 160 | 161 | - cli-<支持解析args参数的库> `用于更快速的开发cli应用` 162 | - desktop-<Swing/AWT> `其他GUI实现方式` 163 | - web-<轻量级无容器的http-server库> `其他Web实现方式` 164 | 165 | ## 技术交流 166 | 167 | - Q群:[707416319](https://qm.qq.com/cgi-bin/qm/qr?k=uSAXH8sKqQnF_cvDSF4T8IN7tSqabAJ3&jump_from=webapi) 168 | - 关于作者:[I'm westinyang](https://kaihongpai.feishu.cn/wiki/CqWLwJRadibxztkrIWZcogWxnXd) 169 | 170 | ## 参考资料 171 | 172 | - 官方资料 173 | - [GraalVM 入门](https://www.graalvm.org/docs/getting-started/) 174 | - [native-image 文档](https://www.graalvm.org/reference-manual/native-image/) 175 | - [JavaFX 中文官网](https://openjfx.cn/) `推荐阅读` 176 | - [Spring Native for GraalVM 文档](https://repo.spring.io/milestone/org/springframework/experimental/spring-graalvm-native-docs/0.8.5/spring-graalvm-native-docs-0.8.5.zip!/reference/index.html) `推荐阅读` 177 | - 网络文章 178 | - [如何评价 GraalVM 这个项目?](https://www.zhihu.com/question/274042223) `推荐阅读` 179 | - [GraalVM:微服务时代的Java](https://www.zhihu.com/column/p/137836206) `推荐阅读` `很全面的讲解` 180 | - [为 JavaFX 应用生成 native image](https://zhuanlan.zhihu.com/p/103606559?utm_source=wechat_session) 181 | - [Windows 下使用 GraalVM 将 JavaFX 应用编译成 exe](https://www.cnblogs.com/dehai/p/14258391.html) 182 | - [Spring Boot as GraalVM Native Images](https://blog.codecentric.de/en/2020/05/spring-boot-graalvm/) `推荐阅读` `可能需要“出国留学”工具` 183 | - [Spring Boot GraalVM Native Image builds with the native-image-maven-plugin](https://blog.codecentric.de/en/2020/05/spring-boot-graalvm/) `推荐阅读` `可能需要“出国留学”工具` 184 | - [如何借助 Graalvm 和 Picocli 构建 Java 编写的原生 CLI 应用](https://www.infoq.cn/article/4RRJuxPRE80h7YsHZJtX) `推荐阅读` 185 | -------------------------------------------------------------------------------- /cli-normal/native-image-agent.bat: -------------------------------------------------------------------------------- 1 | java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image -jar ./target/cli-normal-1.0.jar -------------------------------------------------------------------------------- /cli-normal/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | java-graalvm-start 7 | com.mueeee 8 | 1.0 9 | 10 | 11 | 4.0.0 12 | 13 | cli-normal 14 | 1.0 15 | 16 | 17 | UTF-8 18 | 21 19 | ${java.version} 20 | ${java.version} 21 | 23.1.0 22 | 26 | 0.9.27 27 | com.mueeee.clinormal.CliNormalApp 28 | 29 | 30 | 31 | 32 | org.graalvm.sdk 33 | graal-sdk 34 | ${graalvm.version} 35 | provided 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 3.8.1 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-assembly-plugin 49 | 50 | ${project.build.finalName} 51 | 52 | 53 | ${start-class} 54 | 55 | 56 | 57 | jar-with-dependencies 58 | 59 | false 60 | 61 | 62 | 63 | make-assembly 64 | package 65 | 66 | single 67 | 68 | 69 | 70 | 71 | 72 | org.graalvm.buildtools 73 | native-maven-plugin 74 | ${native.maven.plugin.version} 75 | 76 | false 77 | false 78 | ${project.artifactId} 79 | ${start-class} 80 | 81 | --no-fallback 82 | -H:-CheckToolchain 83 | 84 | 85 | 86 | 87 | true 88 | 89 | 94 | 95 | true 96 | 97 | 98 | 99 | 100 | compile-no-fork 101 | 102 | package 103 | 104 | 105 | 106 | 107 | 108 | 109 | 119 | -------------------------------------------------------------------------------- /cli-normal/src/main/java/com/mueeee/clinormal/CliNormalApp.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.clinormal; 2 | 3 | /** 4 | * Application 5 | */ 6 | public class CliNormalApp { 7 | 8 | public static void main(String[] args) { 9 | System.out.println("Hello GraalVM CLI Application"); 10 | for (String arg : args) { 11 | System.out.println(arg); 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /cli-normal/src/main/resources/app.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/java-graalvm-start/cd738da3de786003daa64dadd6a263670de6b7e1/cli-normal/src/main/resources/app.properties -------------------------------------------------------------------------------- /cli-picocli/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | java-graalvm-start 7 | com.mueeee 8 | 1.0 9 | 10 | 4.0.0 11 | 12 | cli-picocli 13 | 1.0 14 | 15 | 16 | UTF-8 17 | 21 18 | ${java.version} 19 | ${java.version} 20 | 23.1.0 21 | 0.9.27 22 | 4.6.2 23 | 1.2.0 24 | com.mueeee.clipicocli.CliPicocliApp 25 | 26 | 27 | 28 | 29 | org.graalvm.sdk 30 | graal-sdk 31 | ${graalvm.version} 32 | provided 33 | 34 | 35 | info.picocli 36 | picocli 37 | ${picocli.version} 38 | 39 | 40 | 41 | info.picocli 42 | picocli-jansi-graalvm 43 | ${picocli.jansi-graalvm.version} 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-compiler-plugin 52 | 3.8.1 53 | 54 | 55 | 56 | 57 | info.picocli 58 | picocli-codegen 59 | ${picocli.version} 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-assembly-plugin 67 | 68 | ${project.build.finalName} 69 | 70 | 71 | ${start-class} 72 | 73 | 74 | 75 | jar-with-dependencies 76 | 77 | false 78 | 79 | 80 | 81 | make-assembly 82 | package 83 | 84 | single 85 | 86 | 87 | 88 | 89 | 90 | org.graalvm.buildtools 91 | native-maven-plugin 92 | ${native.maven.plugin.version} 93 | 94 | false 95 | false 96 | ${project.artifactId} 97 | ${start-class} 98 | 99 | --no-fallback 100 | -H:-CheckToolchain 101 | 102 | 107 | 108 | true 109 | 110 | 111 | 112 | 113 | compile-no-fork 114 | 115 | package 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /cli-picocli/src/main/java/com/mueeee/clipicocli/CliPicocliApp.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.clipicocli; 2 | 3 | import picocli.CommandLine; 4 | import picocli.CommandLine.Command; 5 | import picocli.CommandLine.Option; 6 | import picocli.CommandLine.Parameters; 7 | import picocli.jansi.graalvm.AnsiConsole; 8 | 9 | import java.io.File; 10 | 11 | @Command(name = "cli-picocli", mixinStandardHelpOptions = true, version = "CliPicocli 1.0") 12 | public class CliPicocliApp implements Runnable { 13 | 14 | // 详细模式 15 | @Option(names = {"-v", "--verbose"}, description = "Verbose mode. Helpful for troubleshooting.") 16 | private boolean verbose = false; 17 | 18 | // 文件处理方式 19 | @Option(names = {"-t", "--type"}, description = "File process mode", defaultValue = "1", showDefaultValue = CommandLine.Help.Visibility.ALWAYS) 20 | private String type = ""; 21 | 22 | // 多个文件参数 23 | @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.") 24 | private File[] inputFiles; 25 | 26 | public void run() { 27 | if (verbose) { 28 | System.out.println(inputFiles.length + " files to process..."); 29 | } 30 | if (type != null) { 31 | System.out.println("File processing mode: " + type); 32 | } 33 | for (File f : inputFiles) { 34 | System.out.println(f.getAbsolutePath()); 35 | } 36 | } 37 | 38 | public static void main(String[] args) { 39 | // By implementing Runnable or Callable, parsing, error handling and handling user 40 | // requests for usage help or version help can be done with one line of code. 41 | 42 | // int exitCode = new CommandLine(new CliPicocliApp()).execute(args); 43 | // System.exit(exitCode); 44 | 45 | int exitCode = 0; 46 | // 在 Windows 上启用颜色 47 | try (AnsiConsole ansi = AnsiConsole.windowsInstall()) { 48 | exitCode = new CommandLine(new CliPicocliApp()).execute(args); 49 | } 50 | System.exit(exitCode); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cli-picocli/src/main/resources/app.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/java-graalvm-start/cd738da3de786003daa64dadd6a263670de6b7e1/cli-picocli/src/main/resources/app.properties -------------------------------------------------------------------------------- /desktop-javafx/README.md: -------------------------------------------------------------------------------- 1 | - [Add Icon to Windows native binary](https://github.com/gluonhq/substrate/pull/1090#issuecomment-1479999989) 2 | - [Maven 插件:尚不支持 Maven 运行时 3.9.0(在这种情况下,将引发错误,要求降级到 3.8.8 或更低版本)](https://docs.gluonhq.com/#_what_is_new) `1.0.17` 3 | ```log 4 | Maven version 3.9.2 is not currently supported by the GluonFX Maven Plugin. 5 | Please downgrade your Maven version to 3.8.8 and then try again. 6 | ``` 7 | - [Couldn't determine GraalVM version](https://github.com/gluonhq/gluonfx-maven-plugin/issues/489) 8 | - gluonfx-maven-plugin对于刚出的21支持有问题,其根本原因在于所使用的substrate 0.60存在的版本识别问题,在0.61中修复,gluonfx-maven-plugin在1.0.22版本中升级到substrate 0.61解决了这个问题 9 | - Native-image building on Windows currently only supports target architecture: AMD64 (?? unsupported)) 10 | - GluonFx + GraalVM 21,21之前的版本没有此问题,非GluonFx插件项目的没有此问题 11 | - 更改VS语言包删除中文 或 修改 系统语言设置等,暂不考虑此方案 12 | - 添加构建参数 `-H:-CheckToolchain`,跳过环境检查,使用此方案 13 | -------------------------------------------------------------------------------- /desktop-javafx/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | java-graalvm-start 7 | com.mueeee 8 | 1.0 9 | 10 | 11 | 4.0.0 12 | 13 | desktop-javafx 14 | 1.0 15 | 16 | 17 | UTF-8 18 | 21 19 | ${java.version} 20 | ${java.version} 21 | 22 | 23 | 21-ea+5 24 | 21-ea+5 25 | 32 | 1.0.22 33 | com.mueeee.desktopjavafx.App 34 | 35 | 36 | 37 | 38 | org.openjfx 39 | javafx-controls 40 | ${javafx.version} 41 | 42 | 43 | org.openjfx 44 | javafx-fxml 45 | ${javafx.version} 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-compiler-plugin 54 | 3.8.1 55 | 56 | ${java.version} 57 | 58 | 59 | 60 | org.openjfx 61 | javafx-maven-plugin 62 | 0.0.8 63 | 64 | ${start-class} 65 | 66 | 67 | 68 | com.gluonhq 69 | gluonfx-maven-plugin 70 | ${gluonfx-maven-plugin.version} 71 | 72 | ${start-class} 73 | 76 | ${javafx.staticSdk.version} 77 | 78 | 81 | 82 | 83 | .*\\.properties$ 84 | 85 | 86 | 87 | com.mueeee.desktopjavafx.ctrl.MainCtrl 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 101 | --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk=ALL-UNNAMED 102 | 103 | 110 | -H:-CheckToolchain 111 | 112 | 113 | 114 | 115 | desktop-javafx 116 | muetech 117 | ${version} 118 | 119 | false 120 | muetech 121 | 122 | 123 | 124 | 125 | 126 | 127 | build 128 | 129 | package 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/java/com/mueeee/desktopjavafx/App.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.desktopjavafx; 2 | 3 | import com.mueeee.desktopjavafx.conf.AppConfig; 4 | import javafx.application.Application; 5 | import javafx.application.Platform; 6 | import javafx.fxml.FXMLLoader; 7 | import javafx.scene.Parent; 8 | import javafx.scene.Scene; 9 | import javafx.scene.control.Alert; 10 | import javafx.scene.image.Image; 11 | import javafx.stage.Screen; 12 | import javafx.stage.Stage; 13 | 14 | import java.io.IOException; 15 | import java.util.regex.Pattern; 16 | 17 | /** 18 | * JavaFx Application 19 | * 20 | * 开发时如果直接启动这个类,会报找不到组件或其他错误信息,需要在IDEA启动项中配置如下jvm参数 21 | * --module-path "D:\dev\javafx-sdk-15.0.1\lib" --add-modules javafx.controls,javafx.fxml 22 | * 关于这个问题,还有另一种解决方案,另外创建一个主类,然后类调用默认的启动类。请运行:DesktopJavaFxApp 23 | * 24 | * 官方文档:https://openjfx.io/openjfx-docs/ 25 | * 错误原因:https://my.oschina.net/tridays/blog/2222909 26 | */ 27 | public class App extends Application { 28 | 29 | private static Scene scene; 30 | 31 | public static void main(String[] args) { 32 | // 解决Linux上编译为native-image时运行错误: 33 | String osName = System.getProperty("os.name", ""); 34 | if (Pattern.matches("Linux.*", osName)) { 35 | System.setProperty("prism.forceGPU", "true"); 36 | } 37 | // Init & Launch 38 | AppConfig.init(); 39 | launch(); 40 | } 41 | 42 | @Override 43 | public void init() throws Exception { 44 | System.out.println("init"); 45 | super.init(); 46 | // 设置系统屏幕缩放比例 47 | try { 48 | var scaleX = Screen.getScreens().get(0).getOutputScaleX(); 49 | System.setProperty("glass.win.uiScale", String.valueOf(scaleX)); 50 | } catch (Exception ignored) { 51 | System.setProperty("glass.win.uiScale", "1.0"); 52 | } 53 | // 在非JavaFX应用程序主线程上运行指定的Runnable 54 | /*Platform.runLater(() -> { 55 | Alert alert = new Alert(Alert.AlertType.INFORMATION); 56 | alert.setContentText("Content Text"); 57 | alert.show(); 58 | });*/ 59 | } 60 | 61 | @Override 62 | public void start(Stage stage) throws IOException { 63 | System.out.println("start"); 64 | // 加载并创建主场景 65 | Parent root = loadFXML("fxml/Main"); 66 | scene = new Scene(root, AppConfig.stageWidth, AppConfig.stageHeight); 67 | // 设置窗口信息 68 | stage.setTitle(AppConfig.title); 69 | stage.setResizable(AppConfig.stageResizable); 70 | stage.getIcons().add(new Image(App.class.getResourceAsStream(AppConfig.icon))); 71 | stage.setScene(scene); 72 | stage.show(); 73 | } 74 | 75 | @Override 76 | public void stop() throws Exception { 77 | System.out.println("stop"); 78 | super.stop(); 79 | } 80 | 81 | public static void setRoot(String fxml) throws IOException { 82 | scene.setRoot(loadFXML(fxml)); 83 | } 84 | 85 | private static Parent loadFXML(String fxml) throws IOException { 86 | FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); 87 | return fxmlLoader.load(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/java/com/mueeee/desktopjavafx/DesktopJavaFxApp.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.desktopjavafx; 2 | 3 | /** 4 | * Startup Application 5 | */ 6 | public class DesktopJavaFxApp { 7 | 8 | public static void main(String[] args) { 9 | App.main(args); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/java/com/mueeee/desktopjavafx/conf/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.desktopjavafx.conf; 2 | 3 | import com.mueeee.desktopjavafx.App; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Properties; 8 | 9 | /** 10 | * 应用配置 11 | */ 12 | public class AppConfig { 13 | // 应用标题 14 | public static String title = "JavaFx Application"; 15 | // 应用图标 16 | public static String icon = "icon/icon.png"; 17 | // 窗口宽度 18 | public static int stageWidth = 640; 19 | // 窗口高度 20 | public static int stageHeight = 480; 21 | // 允许调整窗口尺寸 22 | public static boolean stageResizable = true; 23 | 24 | public static void init() { 25 | try { 26 | Properties properties = new Properties(); 27 | InputStream in = App.class.getResourceAsStream("app.properties"); 28 | properties.load(in); 29 | title = properties.getProperty("title"); 30 | icon = properties.getProperty("icon"); 31 | stageWidth = Integer.parseInt(properties.getProperty("stage.width")); 32 | stageHeight = Integer.parseInt(properties.getProperty("stage.height")); 33 | stageResizable = Boolean.parseBoolean(properties.getProperty("stage.resizable")); 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/java/com/mueeee/desktopjavafx/ctrl/MainCtrl.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.desktopjavafx.ctrl; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.Initializable; 5 | import javafx.scene.control.Alert; 6 | import javafx.scene.control.Button; 7 | import javafx.scene.control.Label; 8 | import javafx.scene.layout.Pane; 9 | import javafx.stage.FileChooser; 10 | import javafx.stage.Window; 11 | 12 | import java.io.File; 13 | import java.net.URL; 14 | import java.util.ResourceBundle; 15 | 16 | /** 17 | * 主界面控制器 18 | */ 19 | public class MainCtrl implements Initializable { 20 | 21 | // 主容器 22 | public Pane rootPane; 23 | 24 | public Button btnAlert, btnChooseFile; 25 | 26 | public void initialize(URL location, ResourceBundle resources) { 27 | System.out.println("initialize: " + location.getPath()); 28 | } 29 | 30 | /** 31 | * 弹出框按钮单击事件 32 | * @param actionEvent 33 | */ 34 | public void onBtnAlertClick(ActionEvent actionEvent) { 35 | String javaVersion = System.getProperty("java.version"); 36 | String javafxVersion = System.getProperty("javafx.version"); 37 | // ... 38 | Alert alert = new Alert(Alert.AlertType.INFORMATION); 39 | alert.setHeaderText(null); 40 | alert.setContentText("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + "."); 41 | alert.show(); 42 | } 43 | 44 | /** 45 | * 选择文件按钮单机事件 46 | * @param actionEvent 47 | */ 48 | public void onBtnChooseFileClick(ActionEvent actionEvent) { 49 | Window window = rootPane.getScene().getWindow(); 50 | FileChooser fileChooser = new FileChooser(); 51 | // 文件类型过滤器 52 | /*FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Excel files (*.xls, *.xlsx)", "*.xls", "*.xlsx"); 53 | fileChooser.getExtensionFilters().add(filter);*/ 54 | // ... 55 | File file = fileChooser.showOpenDialog(window); 56 | String fileName = file == null ? "" : file.getName(); 57 | String fileAbsolutePath = file == null ? "" : file.getAbsolutePath(); 58 | 59 | if (file != null) { 60 | Alert alert = new Alert(Alert.AlertType.INFORMATION); 61 | alert.setContentText("文件路径:" + fileAbsolutePath); 62 | alert.show(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/resources/com/mueeee/desktopjavafx/app.properties: -------------------------------------------------------------------------------- 1 | title=GraalVM & JavaFX Application 2 | icon=icon/icon.png 3 | stage.width=640 4 | stage.height=440 5 | stage.resizable=false -------------------------------------------------------------------------------- /desktop-javafx/src/main/resources/com/mueeee/desktopjavafx/css/Main.css: -------------------------------------------------------------------------------- 1 | .root { 2 | /*-fx-background-color: #f0f0f0;*/ 3 | } 4 | -------------------------------------------------------------------------------- /desktop-javafx/src/main/resources/com/mueeee/desktopjavafx/fxml/Main.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |