├── .github
├── release.yml
└── workflows
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
├── src
├── main
│ └── java
│ │ └── org
│ │ └── openjfx
│ │ └── gradle
│ │ ├── JavaFXModule.java
│ │ ├── JavaFXOptions.java
│ │ ├── JavaFXPlatform.java
│ │ ├── JavaFXPlugin.java
│ │ └── metadatarule
│ │ └── JavaFXComponentMetadataRule.java
└── test
│ └── java
│ └── org
│ └── openjfx
│ └── gradle
│ ├── JavaFXModuleTest.java
│ ├── JavaFXPluginSmokeTest.java
│ ├── JavaFXPluginSmokeTestGradle64.java
│ ├── JavaFXPluginSmokeTestGradle69.java
│ ├── JavaFXPluginSmokeTestGradle76.java
│ ├── JavaFXPluginSmokeTestGradle814.java
│ ├── JavaFXPluginSmokeTestGradle814CC.java
│ ├── JavaFXPluginSmokeTestGradle83.java
│ ├── JavaFXPluginSmokeTestGradle87.java
│ └── JavaFXPluginSmokeTestGradle87CC.java
└── test-project
├── build.gradle
├── local-sdk
├── build.gradle
├── javafx-sdk-17.0.8
│ └── lib
│ │ ├── javafx.base.jar
│ │ ├── javafx.controls.jar
│ │ └── javafx.graphics.jar
└── src
│ └── main
│ └── java
│ └── org
│ └── openjfx
│ └── gradle
│ └── javafx
│ └── test
│ └── Main.java
├── modular-with-modularity-plugin
├── build.gradle
└── src
│ └── main
│ └── java
│ ├── module-info.java
│ └── org
│ └── openjfx
│ └── gradle
│ └── javafx
│ └── test
│ └── Main.java
├── modular
├── build.gradle
└── src
│ └── main
│ └── java
│ ├── module-info.java
│ └── org
│ └── openjfx
│ └── gradle
│ └── javafx
│ └── test
│ └── Main.java
├── non-modular
├── build.gradle
└── src
│ └── main
│ └── java
│ └── org
│ └── openjfx
│ └── gradle
│ └── javafx
│ └── test
│ └── Main.java
├── settings.gradle
└── transitive
├── build.gradle
└── src
└── main
└── java
└── org
└── openjfx
└── gradle
└── javafx
└── test
└── Main.java
/.github/release.yml:
--------------------------------------------------------------------------------
1 | changelog:
2 | exclude:
3 | labels:
4 | - housekeeping
5 | authors:
6 | - gluon-bot
7 | categories:
8 | - title: What’s Changed
9 | labels:
10 | - "*"
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 |
9 | jobs:
10 | gradlevalidation:
11 | name: "Validate Gradle Wrapper"
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: gradle/actions/wrapper-validation@v4
16 | build:
17 | name: Build
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v4
22 |
23 | - name: Setup Java
24 | uses: actions/setup-java@v4
25 | with:
26 | distribution: 'temurin'
27 | java-version: '11'
28 |
29 | - name: Build and verify project
30 | run: |
31 | export DISPLAY=:90
32 | Xvfb -ac :90 -screen 0 1280x1024x24 > /dev/null 2>&1 &
33 | ./gradlew clean build -i
34 |
35 | - name: Publish Snapshots
36 | if: github.ref == 'refs/heads/master'
37 | run: |
38 | # Find project version
39 | ver=$(./gradlew properties -q | grep "version:" | awk '{print $2}')
40 | # deploy if snapshot found
41 | if [[ $ver == *"SNAPSHOT"* ]]
42 | then
43 | ./gradlew publish -PsonatypeUsername=$SONATYPE_USERNAME -PsonatypePassword=$SONATYPE_PASSWORD
44 | fi
45 | shell: bash
46 | env:
47 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
48 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
49 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | tags:
5 | - '*'
6 |
7 | jobs:
8 | build:
9 | name: release
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | with:
15 | fetch-depth: 5
16 |
17 | - name: Setup Java
18 | uses: actions/setup-java@v4
19 | with:
20 | distribution: 'temurin'
21 | java-version: '11'
22 |
23 | - name: Build and verify project
24 | run: |
25 | export DISPLAY=:90
26 | Xvfb -ac :90 -screen 0 1280x1024x24 > /dev/null 2>&1 &
27 | ./gradlew clean build -i
28 |
29 | - name: Publish to Gradle plugin repository
30 | id: deploy
31 | run: |
32 | ./gradlew publishPlugins -Pgradle.publish.key=$PUBLISH_KEY -Pgradle.publish.secret=$PUBLISH_SECRET
33 | shell: bash
34 | env:
35 | PUBLISH_KEY: ${{ secrets.PUBLISH_KEY }}
36 | PUBLISH_SECRET: ${{ secrets.PUBLISH_SECRET }}
37 |
38 | - name: Commit next development version
39 | if: steps.deploy.outputs.exit_code == 0
40 | run: |
41 | git config user.email "githubbot@gluonhq.com"
42 | git config user.name "Gluon Bot"
43 | TAG=${GITHUB_REF/refs\/tags\//}
44 | # Update README with the latest released version
45 | sed -i "0,/id 'org.openjfx.javafxplugin' version '.*'/s//id 'org.openjfx.javafxplugin' version '$TAG'/" README.md
46 | sed -i "0,/id(\"org.openjfx.javafxplugin\") version \".*\"/s//id(\"org.openjfx.javafxplugin\") version \"$TAG\"/" README.md
47 | sed -i "0,/'org.openjfx:javafx-plugin:.*'/s//'org.openjfx:javafx-plugin:$TAG'/" README.md
48 | sed -i "0,/\"org.openjfx:javafx-plugin:.*\"/s//\"org.openjfx:javafx-plugin:$TAG\"/" README.md
49 | git commit README.md -m "Use latest release v$TAG in README"
50 | # Update project version
51 | newVersion=${TAG%.*}.$((${TAG##*.} + 1))
52 | echo "Update project version to next snapshot version"
53 | sed -i "0,/^version = '$TAG'/s//version = '$newVersion-SNAPSHOT'/" build.gradle
54 | git commit build.gradle -m "Prepare development of $newVersion"
55 | git push https://github.com/openjfx/javafx-gradle-plugin HEAD:master
56 | env:
57 | PAT: ${{ secrets.GITHUB_TOKEN }}
58 |
59 | - name: Create GitHub release
60 | uses: softprops/action-gh-release@v1
61 | with:
62 | generate_release_notes: true
63 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle/
2 | .idea/
3 | build/
4 | *.iml
5 | out/
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018, Gluon
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of the copyright holder nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaFX Gradle Plugin
2 |
3 | Simplifies working with JavaFX 11+ for gradle projects.
4 |
5 | [](https://plugins.gradle.org/plugin/org.openjfx.javafxplugin)
6 | 
7 | [](https://opensource.org/licenses/BSD-3-Clause)
8 |
9 | ## Getting started
10 |
11 | To use the plugin, apply the following two steps:
12 |
13 | ### 1. Apply the plugin
14 |
15 | ##### Using the `plugins` DSL:
16 |
17 | **Groovy**
18 |
19 | plugins {
20 | id 'org.openjfx.javafxplugin' version '0.1.0'
21 | }
22 |
23 | **Kotlin**
24 |
25 | plugins {
26 | id("org.openjfx.javafxplugin") version "0.1.0"
27 | }
28 |
29 | ##### Alternatively, you can use the `buildscript` DSL:
30 |
31 | **Groovy**
32 |
33 | buildscript {
34 | repositories {
35 | maven {
36 | url "https://plugins.gradle.org/m2/"
37 | }
38 | }
39 | dependencies {
40 | classpath 'org.openjfx:javafx-plugin:0.1.0'
41 | }
42 | }
43 | apply plugin: 'org.openjfx.javafxplugin'
44 |
45 | **Kotlin**
46 |
47 | buildscript {
48 | repositories {
49 | maven {
50 | setUrl("https://plugins.gradle.org/m2/")
51 | }
52 | }
53 | dependencies {
54 | classpath("org.openjfx:javafx-plugin:0.1.0")
55 | }
56 | }
57 | apply(plugin = "org.openjfx.javafxplugin")
58 |
59 |
60 | ### 2. Specify JavaFX modules
61 |
62 | Specify all the JavaFX modules that your project uses:
63 |
64 | **Groovy**
65 |
66 | javafx {
67 | modules = [ 'javafx.controls', 'javafx.fxml' ]
68 | }
69 |
70 | **Kotlin**
71 |
72 | javafx {
73 | modules("javafx.controls", "javafx.fxml")
74 | }
75 |
76 | ### 3. Specify JavaFX version
77 |
78 | To override the default JavaFX version, a version string can be declared.
79 | This will make sure that all the modules belong to this specific version:
80 |
81 | **Groovy**
82 |
83 |
84 | javafx {
85 | version = '17'
86 | modules = [ 'javafx.controls', 'javafx.fxml' ]
87 | }
88 |
89 |
90 | **Kotlin**
91 |
92 |
93 | javafx {
94 | version = "17"
95 | modules("javafx.controls", "javafx.fxml")
96 | }
97 |
98 |
99 | ### 4. Cross-platform projects and libraries
100 |
101 | The plugin will include JavaFX dependencies for the current platform.
102 | However, a different target platform can also be specified.
103 |
104 | Supported targets are:
105 |
106 | * linux
107 | * linux-aarch64
108 | * win or windows
109 | * osx or mac or macos
110 | * osx-aarch64 or mac-aarch64 or macos-aarch64 (support added in JavaFX 11.0.12 LTS and JavaFX 17 GA)
111 |
112 | **Groovy**
113 |
114 |
115 | javafx {
116 | modules = [ 'javafx.controls', 'javafx.fxml' ]
117 | platform = 'mac'
118 | }
119 |
120 |
121 | **Kotlin**
122 |
123 |
124 | javafx {
125 | modules("javafx.controls", "javafx.fxml")
126 | platform = 'mac'
127 | }
128 |
129 |
130 |
131 | ### 5. Dependency scope
132 |
133 | JavaFX application require native binaries for each platform to run.
134 | By default, the plugin will include these binaries for the target platform.
135 | Native dependencies can be avoided by declaring the dependency configuration as **compileOnly**.
136 |
137 | **Groovy**
138 |
139 |
140 | javafx {
141 | modules = [ 'javafx.controls', 'javafx.fxml' ]
142 | configuration = 'compileOnly'
143 | }
144 |
145 |
146 | **Kotlin**
147 |
148 |
149 | javafx {
150 | modules("javafx.controls", "javafx.fxml")
151 | configuration = "compileOnly"
152 | }
153 |
154 |
155 | Multiple configurations can also be targeted by using `configurations`.
156 | For example, JavaFX dependencies can be added to both `implementation` and `testImplementation`.
157 |
158 | **Groovy**
159 |
160 |
161 | javafx {
162 | modules = [ 'javafx.controls', 'javafx.fxml' ]
163 | configurations = [ 'implementation', 'testImplementation' ]
164 | }
165 |
166 |
167 | **Kotlin**
168 |
169 |
170 | javafx {
171 | modules("javafx.controls", "javafx.fxml")
172 | configurations("implementation", "testImplementation")
173 | }
174 |
175 |
176 | ### 5. Using a local JavaFX SDK
177 |
178 | By default, JavaFX modules are retrieved from Maven Central.
179 | However, a local JavaFX SDK can be used instead, for instance in the case of
180 | a custom build of OpenJFX.
181 |
182 | Setting a valid path to the local JavaFX SDK will take precedence:
183 |
184 | **Groovy**
185 |
186 |
187 | javafx {
188 | sdk = '/path/to/javafx-sdk'
189 | modules = [ 'javafx.controls', 'javafx.fxml' ]
190 | }
191 |
192 |
193 | **Kotlin**
194 |
195 |
196 | javafx {
197 | sdk = "/path/to/javafx-sdk"
198 | modules("javafx.controls", "javafx.fxml")
199 | }
200 |
201 |
202 | ## Issues and Contributions
203 |
204 | Issues can be reported to the [Issue tracker](https://github.com/openjfx/javafx-gradle-plugin/issues/).
205 |
206 | Contributions can be submitted via [Pull requests](https://github.com/openjfx/javafx-gradle-plugin/pulls/),
207 | providing you have signed the [Gluon Individual Contributor License Agreement (CLA)](https://cla.gluonhq.com/).
208 |
209 | ## Migrating from 0.0.14 to 0.1.0
210 |
211 | Version `0.1.0` introduced several changes and improvements, including lazy dependency declaration,
212 | variant-aware dependency management, and support for Gradle's built-in JPMS functionality. In the
213 | previous version, the classpath/module path was rewritten. This is no longer the case. As a result,
214 | your past builds might be affected when you upgrade the plugin. In the next section, there are a few
215 | troubleshooting steps that might help with the transition if you encounter issues when upgrading.
216 | These examples are provided on a best-effort basis, but feel free to open an issue if you believe
217 | there's a migration scenario not covered here that should be included.
218 |
219 | ### Troubleshooting
220 |
221 | #### Gradle version
222 |
223 | The plugin now requires `Gradle 6.1` or higher. Consider updating your Gradle settings, wrapper,
224 | and build to a more recent version of Gradle. Additionally, updating your plugins and dependencies
225 | can help minimize issues with the plugin.
226 |
227 | #### Mixed JavaFX jars
228 |
229 | If you encounter mixed classified JavaFX jars or see errors like `Error initializing QuantumRenderer: no
230 | suitable pipeline found` during executing task like `build`, `test`, `assemble`, etc., it is likely one
231 | or more of your dependencies have published metadata that includes JavaFX dependencies with classifiers.
232 | The ideal solution is to reach out to library authors to update their JavaFX plugin and publish a patch
233 | with fixed metadata. A fallback solution to this is to `exclude group: 'org.openjfx'` on the dependencies
234 | causing the issue.
235 |
236 | ```groovy
237 | implementation('com.example.fx:foo:1.0.0') {
238 | exclude group: 'org.openjfx', module: '*'
239 | }
240 | ```
241 |
242 | #### Variants
243 |
244 | If you encounter errors such as `Cannot choose between the following variants of org.openjfx...` it is possible
245 | that your build or another plugin is interacting with the classpath/module path in a way that "breaks" functionality
246 | provided by this plugin. In such cases, you may need to re-declare the variants yourself as described in [Gradle docs
247 | on attribute matching/variants](https://docs.gradle.org/current/userguide/variant_attributes.html) or reach out to
248 | the plugin author in an attempt to remediate the situation.
249 |
250 | ```groovy
251 | // Approach 1: Explicit Variant
252 | // The following snippet will let you add attributes for linux and x86_64 to a configuration
253 | configurations.someConfiguration {
254 | attributes {
255 | attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
256 | attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, objects.named(OperatingSystemFamily, "linux"))
257 | attribute(MachineArchitecture.ARCHITECTURE_ATTRIBUTE, objects.named(MachineArchitecture, "x86-64"))
258 | }
259 | }
260 |
261 | // Approach 2: Copy existing configuration into another configuration
262 | configurations.someConfiguration {
263 | def runtimeAttributes = configurations.runtimeClasspath.attributes
264 | runtimeAttributes.keySet().each { key ->
265 | attributes.attribute(key, runtimeAttributes.getAttribute(key))
266 | }
267 | }
268 | ```
269 |
270 | #### Extra plugins
271 |
272 | In versions `0.0.14` and below, there was a transitive dependency on `org.javamodularity.moduleplugin`.
273 | If your **modular** project stops working after updating to `0.1.0` or above, it is likely that you need to
274 | explicitly add the [org.javamodularity.moduleplugin](https://plugins.gradle.org/plugin/org.javamodularity.moduleplugin)
275 | back to your build and set `java.modularity.inferModulePath.set(false)` to keep things working as they were.
276 | This plugin helped with transitive dependencies on legacy jars that haven't been modularized yet, but now you
277 | have to option choose which approach to take. This change should not be required for non-modular projects.
278 |
279 | **Before**
280 |
281 | ````groovy
282 | plugins {
283 | id 'org.openjfx.javafxplugin' version '0.0.14'
284 | }
285 | ````
286 |
287 | **After**
288 |
289 | ````groovy
290 | plugins {
291 | id 'org.openjfx.javafxplugin' version '0.1.0'
292 | id 'org.javamodularity.moduleplugin' version '1.8.12'
293 | }
294 |
295 | java {
296 | modularity.inferModulePath.set(false)
297 | }
298 | ````
299 |
300 | **Note**: There are other recommended alternatives over `org.javamodularity.moduleplugin` for modular projects such as
301 | [extra-java-module-info](https://github.com/gradlex-org/extra-java-module-info) that would allow you to keep
302 | `inferModulePath` set to **true** by declaring missing module information from legacy jars. More details on how to
303 | accomplish can be found on the plugin's source code repository.
304 |
305 | #### Dependency hierarchy
306 |
307 | Version `0.1.0` now relies on JavaFX modules defining their transitive modules rather than flattening them.
308 | This change allows you to publish metadata declaring only the JavaFX modules you need, meaning it does not
309 | include transitive JavaFX modules as part of your published metadata.
310 |
311 | Some plugins rely on having all modules (transitive included) declared as "top-level" modules such as the
312 | `badass-runtime-plugin` on **non-modular** projects. In this particular case, it is necessary to declare
313 | all modules to restore previous functionality from `0.0.14` and below.
314 |
315 | **Before**
316 |
317 | ````groovy
318 | javafx {
319 | modules = ['javafx.controls']
320 | }
321 | ````
322 |
323 | **After**
324 |
325 | ````groovy
326 | javafx {
327 | modules = ['javafx.base', 'javafx.graphics', 'javafx.controls']
328 | }
329 | ````
330 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.gradle.plugin-publish' version '1.2.1'
3 | id 'com.github.ben-manes.versions' version '0.47.0'
4 | id 'com.github.hierynomus.license' version '0.16.1'
5 | }
6 |
7 | group = 'org.openjfx'
8 | version = '0.1.1-SNAPSHOT'
9 |
10 | java {
11 | toolchain.languageVersion = JavaLanguageVersion.of(11)
12 | }
13 |
14 | repositories {
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 |
19 | dependencies {
20 | implementation 'com.google.gradle:osdetector-gradle-plugin:1.7.3'
21 |
22 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
23 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
24 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
25 | }
26 |
27 | tasks.named('test', Test) {
28 | useJUnitPlatform()
29 | }
30 |
31 | gradlePlugin {
32 | plugins {
33 | javafxPlugin {
34 | id = 'org.openjfx.javafxplugin'
35 | displayName = 'JavaFX Gradle Plugin'
36 | description = 'Plugin that makes it easy to work with JavaFX'
37 | implementationClass = 'org.openjfx.gradle.JavaFXPlugin'
38 | website = 'https://github.com/openjfx/javafx-gradle-plugin'
39 | vcsUrl = 'https://github.com/openjfx/javafx-gradle-plugin'
40 | tags.set(['java', 'javafx'])
41 | }
42 | }
43 | }
44 |
45 | publishing {
46 | repositories {
47 | maven {
48 | url = "https://oss.sonatype.org/content/repositories/snapshots/"
49 | def sonatypeUsername = providers.gradleProperty('sonatypeUsername')
50 | def sonatypePassword = providers.gradleProperty('sonatypePassword')
51 | if (sonatypeUsername.isPresent() && sonatypePassword.isPresent()) {
52 | credentials {
53 | username = sonatypeUsername.get()
54 | password = sonatypePassword.get()
55 | }
56 | }
57 | }
58 | }
59 | }
60 |
61 | license {
62 | skipExistingHeaders = true
63 | mapping {
64 | java = 'SLASHSTAR_STYLE'
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openjfx/javafx-gradle-plugin/9f43de5cd4628e44f70c66659011588e06e5f081/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command;
206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
207 | # shell script including quotes and variable substitutions, so put them in
208 | # double quotes to make sure that they get re-expanded; and
209 | # * put everything else in single quotes, so that it's not re-expanded.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.gradle.enterprise' version '3.14.1'
3 | }
4 |
5 | gradleEnterprise {
6 | buildScan {
7 | termsOfServiceUrl = 'https://gradle.com/terms-of-service'
8 | termsOfServiceAgree = 'yes'
9 | }
10 | }
11 |
12 | rootProject.name = 'javafx-plugin'
13 |
--------------------------------------------------------------------------------
/src/main/java/org/openjfx/gradle/JavaFXModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import org.gradle.api.GradleException;
33 |
34 | import java.util.Collection;
35 | import java.util.List;
36 | import java.util.Locale;
37 | import java.util.Optional;
38 | import java.util.Set;
39 | import java.util.regex.Pattern;
40 | import java.util.stream.Collectors;
41 | import java.util.stream.Stream;
42 |
43 | public enum JavaFXModule {
44 |
45 | BASE,
46 | GRAPHICS(BASE),
47 | CONTROLS(BASE, GRAPHICS),
48 | FXML(BASE, GRAPHICS),
49 | MEDIA(BASE, GRAPHICS),
50 | SWING(BASE, GRAPHICS),
51 | WEB(BASE, CONTROLS, GRAPHICS, MEDIA);
52 |
53 | static final String PREFIX_MODULE = "javafx.";
54 | private static final String PREFIX_ARTIFACT = "javafx-";
55 |
56 | private final List dependentModules;
57 |
58 | JavaFXModule(JavaFXModule...dependentModules) {
59 | this.dependentModules = List.of(dependentModules);
60 | }
61 |
62 | public static Optional fromModuleName(String moduleName) {
63 | return Stream.of(JavaFXModule.values())
64 | .filter(javaFXModule -> moduleName.equals(javaFXModule.getModuleName()))
65 | .findFirst();
66 | }
67 |
68 | public String getModuleName() {
69 | return PREFIX_MODULE + name().toLowerCase(Locale.ROOT);
70 | }
71 |
72 | public String getModuleJarFileName() {
73 | return getModuleName() + ".jar";
74 | }
75 |
76 | public String getArtifactName() {
77 | return PREFIX_ARTIFACT + name().toLowerCase(Locale.ROOT);
78 | }
79 |
80 | public boolean compareJarFileName(JavaFXPlatform platform, String jarFileName) {
81 | Pattern p = Pattern.compile(getArtifactName() + "-.+-" + platform.getClassifier() + "\\.jar");
82 | return p.matcher(jarFileName).matches();
83 | }
84 |
85 | public static Set getJavaFXModules(Collection moduleNames) {
86 | validateModules(moduleNames);
87 | return moduleNames.stream()
88 | .map(JavaFXModule::fromModuleName)
89 | .flatMap(Optional::stream)
90 | .collect(Collectors.toSet());
91 | }
92 |
93 | public static void validateModules(Collection moduleNames) {
94 | var invalidModules = moduleNames.stream()
95 | .filter(module -> JavaFXModule.fromModuleName(module).isEmpty())
96 | .collect(Collectors.toList());
97 |
98 | if (! invalidModules.isEmpty()) {
99 | throw new GradleException("Found one or more invalid JavaFX module names: " + invalidModules);
100 | }
101 | }
102 |
103 | public List getDependentModules() {
104 | return dependentModules;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/org/openjfx/gradle/JavaFXOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import com.google.gradle.osdetector.OsDetector;
33 | import org.gradle.api.artifacts.Configuration;
34 | import org.gradle.api.artifacts.ConfigurationContainer;
35 | import org.gradle.api.artifacts.dsl.DependencyHandler;
36 | import org.gradle.api.artifacts.dsl.RepositoryHandler;
37 | import org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository;
38 | import org.gradle.api.model.ObjectFactory;
39 | import org.gradle.api.provider.Property;
40 | import org.gradle.api.provider.SetProperty;
41 | import org.gradle.api.tasks.SourceSetContainer;
42 | import org.gradle.nativeplatform.MachineArchitecture;
43 | import org.gradle.nativeplatform.OperatingSystemFamily;
44 |
45 | import javax.inject.Inject;
46 | import java.io.File;
47 | import java.util.HashMap;
48 | import java.util.HashSet;
49 | import java.util.List;
50 | import java.util.Map;
51 | import java.util.Set;
52 | import java.util.stream.Stream;
53 |
54 | abstract public class JavaFXOptions {
55 |
56 | static final String MAVEN_JAVAFX_ARTIFACT_GROUP_ID = "org.openjfx";
57 | private static final String JAVAFX_SDK_LIB_FOLDER = "lib";
58 | private final SetProperty modules;
59 | private final Property platform;
60 |
61 |
62 | private String version = "17";
63 | private String sdk;
64 | private String[] configurations = new String[] { "implementation" };
65 | private FlatDirectoryArtifactRepository customSDKArtifactRepository;
66 |
67 | private final SourceSetContainer sourceSets;
68 | private final Set seenConfigurations = new HashSet<>();
69 |
70 | @Inject
71 | abstract protected ObjectFactory getObjects();
72 |
73 | @Inject
74 | abstract protected RepositoryHandler getRepositories();
75 |
76 | @Inject
77 | abstract protected ConfigurationContainer getConfigurationContainer();
78 |
79 | @Inject
80 | abstract protected DependencyHandler getDependencies();
81 |
82 | public JavaFXOptions(SourceSetContainer sourceSets, OsDetector osDetector) {
83 | this.sourceSets = sourceSets;
84 | platform = getObjects().property(JavaFXPlatform.class);
85 | getFxPlatform().convention(JavaFXPlatform.detect(osDetector));
86 | setClasspathAttributesForAllSourceSets();
87 | modules = getObjects().setProperty(String.class);
88 | }
89 |
90 |
91 | public JavaFXPlatform getPlatform() {
92 | return getFxPlatform().get();
93 | }
94 |
95 | public Property getFxPlatform(){
96 | return platform;
97 | }
98 |
99 | /**
100 | * Sets the target platform for the dependencies.
101 | * @param platform platform classifier.
102 | * Supported classifiers are linux, linux-aarch64, win/windows, osx/mac/macos or osx-aarch64/mac-aarch64/macos-aarch64.
103 | */
104 | public void setPlatform(String platform) {
105 | this.getFxPlatform().set(JavaFXPlatform.fromString(platform));
106 | setClasspathAttributesForAllSourceSets();
107 | }
108 |
109 | private void setClasspathAttributesForAllSourceSets() {
110 | sourceSets.all(sourceSet -> {
111 | setClasspathAttributes(getConfigurationContainer().getByName(sourceSet.getCompileClasspathConfigurationName()));
112 | setClasspathAttributes(getConfigurationContainer().getByName(sourceSet.getRuntimeClasspathConfigurationName()));
113 | });
114 | }
115 |
116 | private void setClasspathAttributes(Configuration classpath) {
117 | classpath.getAttributes().attribute(
118 | OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE,
119 | getObjects().named(OperatingSystemFamily.class, platform.get().getOsFamily()));
120 | classpath.getAttributes().attribute(
121 | MachineArchitecture.ARCHITECTURE_ATTRIBUTE,
122 | getObjects().named(MachineArchitecture.class, platform.get().getArch()));
123 | }
124 |
125 | public String getVersion() {
126 | return version;
127 | }
128 |
129 | public void setVersion(String version) {
130 | this.version = version;
131 | }
132 |
133 | /**
134 | * If set, the JavaFX modules will be taken from this local
135 | * repository, and not from Maven Central
136 | * @param sdk, the path to the local JavaFX SDK folder
137 | */
138 | public void setSdk(String sdk) {
139 | this.sdk = sdk;
140 | updateCustomSDKArtifactRepository();
141 | }
142 |
143 | public String getSdk() {
144 | return sdk;
145 | }
146 |
147 | /**
148 | * Set the configuration name for dependencies, e.g.
149 | * 'implementation', 'compileOnly' etc.
150 | * @param configuration The configuration name for dependencies
151 | */
152 | public void setConfiguration(String configuration) {
153 | setConfigurations(new String[] { configuration });
154 | }
155 |
156 | /**
157 | * Set the configurations for dependencies, e.g.
158 | * 'implementation', 'compileOnly' etc.
159 | * @param configurations List of configuration names
160 | */
161 | public void setConfigurations(String[] configurations) {
162 | this.configurations = configurations;
163 | for (String conf : configurations) {
164 | if (!seenConfigurations.contains(conf)) {
165 | declareFXDependencies(conf);
166 | seenConfigurations.add(conf);
167 | }
168 | }
169 | }
170 |
171 | public String getConfiguration() {
172 | return configurations[0];
173 | }
174 |
175 | public String[] getConfigurations() {
176 | return configurations;
177 | }
178 |
179 | public SetProperty getFxModules() {
180 | return modules;
181 | }
182 |
183 | public Set getModules() {
184 | return modules.get();
185 | }
186 |
187 | public void setModules(List modules) {
188 | this.modules.set(modules);
189 |
190 | }
191 |
192 | public void modules(String...moduleNames) {
193 | setModules(List.of(moduleNames));
194 | }
195 |
196 | private void declareFXDependencies(String conf) {
197 | // Use 'withDependencies' to declare the dependencies late (i.e., right before dependency resolution starts).
198 | // This allows users to make multiple modifications to the 'configurations' list at arbitrary times during
199 | // build configuration.
200 | getConfigurationContainer().getByName(conf).withDependencies(dependencySet -> {
201 | if (!List.of(configurations).contains(conf)) {
202 | // configuration was removed: do nothing
203 | return;
204 | }
205 |
206 | var javaFXModules = JavaFXModule.getJavaFXModules(getModules());
207 | if (customSDKArtifactRepository == null) {
208 | javaFXModules.stream()
209 | .sorted()
210 | .forEach(javaFXModule ->
211 | dependencySet.add(getDependencies().create(
212 | MAVEN_JAVAFX_ARTIFACT_GROUP_ID + ":" +
213 | javaFXModule.getArtifactName() + ":" +
214 | getVersion())));
215 | } else {
216 | // Use the list of dependencies of each module to also add direct dependencies for those.
217 | // This is needed, because there is no information about transitive dependencies in the metadata
218 | // of the modules (as there is no such metadata in the local sdk).
219 | var javaFXModulesWithTransitives = Stream.concat(
220 | javaFXModules.stream(),
221 | javaFXModules.stream()
222 | .flatMap(m -> m.getDependentModules().stream()))
223 | .distinct()
224 | .sorted();
225 |
226 | javaFXModulesWithTransitives.forEach(javaFXModule ->
227 | dependencySet.add(getDependencies().create(
228 | Map.of("name", javaFXModule.getModuleName()))));
229 | }
230 | });
231 | }
232 |
233 | private void updateCustomSDKArtifactRepository() {
234 | if (customSDKArtifactRepository != null) {
235 | getRepositories().remove(customSDKArtifactRepository);
236 | customSDKArtifactRepository = null;
237 | }
238 |
239 | if (sdk != null && !sdk.isEmpty()) {
240 | Map dirs = new HashMap<>();
241 | dirs.put("name", "customSDKArtifactRepository");
242 | if (sdk.endsWith(File.separator)) {
243 | dirs.put("dirs", sdk + JAVAFX_SDK_LIB_FOLDER);
244 | } else {
245 | dirs.put("dirs", sdk + File.separator + JAVAFX_SDK_LIB_FOLDER);
246 | }
247 | customSDKArtifactRepository = getRepositories().flatDir(dirs);
248 | }
249 | }
250 | }
251 |
--------------------------------------------------------------------------------
/src/main/java/org/openjfx/gradle/JavaFXPlatform.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import com.google.gradle.osdetector.OsDetector;
33 | import org.gradle.api.GradleException;
34 | import org.gradle.nativeplatform.MachineArchitecture;
35 | import org.gradle.nativeplatform.OperatingSystemFamily;
36 |
37 | import java.util.Arrays;
38 | import java.util.stream.Collectors;
39 |
40 | public enum JavaFXPlatform {
41 |
42 | LINUX("linux", "linux-x86_64", OperatingSystemFamily.LINUX, MachineArchitecture.X86_64),
43 | LINUX_AARCH64("linux-aarch64", "linux-aarch_64", OperatingSystemFamily.LINUX, MachineArchitecture.ARM64),
44 | WINDOWS("win", "windows-x86_64", OperatingSystemFamily.WINDOWS, MachineArchitecture.X86_64),
45 | OSX("mac", "osx-x86_64", OperatingSystemFamily.MACOS, MachineArchitecture.X86_64),
46 | OSX_AARCH64("mac-aarch64", "osx-aarch_64", OperatingSystemFamily.MACOS, MachineArchitecture.ARM64);
47 |
48 | private final String classifier;
49 | private final String osDetectorClassifier;
50 | private final String osFamily;
51 | private final String arch;
52 |
53 | JavaFXPlatform(String classifier, String osDetectorClassifier, String osFamily, String arch) {
54 | this.classifier = classifier;
55 | this.osDetectorClassifier = osDetectorClassifier;
56 | this.osFamily = osFamily;
57 | this.arch = arch;
58 | }
59 |
60 | public String getClassifier() {
61 | return classifier;
62 | }
63 |
64 | public String getOsFamily() {
65 | return osFamily;
66 | }
67 |
68 | public String getArch() {
69 | return arch;
70 | }
71 |
72 | public static JavaFXPlatform detect(OsDetector osDetector) {
73 |
74 | final String osClassifier = osDetector.getClassifier();
75 |
76 | for (JavaFXPlatform platform: values()) {
77 | if (platform.osDetectorClassifier.equals(osClassifier)) {
78 | return platform;
79 | }
80 | }
81 |
82 | String supportedPlatforms = Arrays.stream(values())
83 | .map(p -> p.osDetectorClassifier)
84 | .collect(Collectors.joining("', '", "'", "'"));
85 |
86 | throw new GradleException(
87 | String.format(
88 | "Unsupported JavaFX platform found: '%s'! " +
89 | "This plugin is designed to work on supported platforms only." +
90 | "Current supported platforms are %s.", osClassifier, supportedPlatforms )
91 | );
92 | }
93 |
94 | public static JavaFXPlatform fromString(String platform) {
95 | switch (platform) {
96 | case "linux":
97 | return JavaFXPlatform.LINUX;
98 | case "linux-aarch64":
99 | return JavaFXPlatform.LINUX_AARCH64;
100 | case "win":
101 | case "windows":
102 | return JavaFXPlatform.WINDOWS;
103 | case "osx":
104 | case "mac":
105 | case "macos":
106 | return JavaFXPlatform.OSX;
107 | case "osx-aarch64":
108 | case "mac-aarch64":
109 | case "macos-aarch64":
110 | return JavaFXPlatform.OSX_AARCH64;
111 | }
112 | return valueOf(platform);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/org/openjfx/gradle/JavaFXPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import com.google.gradle.osdetector.OsDetector;
33 | import com.google.gradle.osdetector.OsDetectorPlugin;
34 | import org.gradle.api.*;
35 | import org.gradle.api.file.FileCollection;
36 | import org.gradle.api.plugins.ApplicationPlugin;
37 | import org.gradle.api.plugins.JavaBasePlugin;
38 | import org.gradle.api.provider.Property;
39 | import org.gradle.api.provider.SetProperty;
40 | import org.gradle.api.tasks.JavaExec;
41 | import org.gradle.api.tasks.SourceSetContainer;
42 | import org.gradle.util.GradleVersion;
43 | import org.openjfx.gradle.metadatarule.JavaFXComponentMetadataRule;
44 |
45 | import java.io.File;
46 | import java.util.ArrayList;
47 | import java.util.Arrays;
48 | import java.util.List;
49 |
50 | import static org.openjfx.gradle.JavaFXOptions.MAVEN_JAVAFX_ARTIFACT_GROUP_ID;
51 |
52 | @NonNullApi
53 | public class JavaFXPlugin implements Plugin {
54 |
55 | @Override
56 | public void apply(Project project) {
57 | if (GradleVersion.current().compareTo(GradleVersion.version("6.4")) < 0) {
58 | throw new GradleException("This plugin requires Gradle 6.4+");
59 | }
60 | // Make sure 'java-base' is applied first, which makes the 'SourceSetContainer' available.
61 | // More concrete Java plugins that build on top of 'java-base' – like 'java-library' or 'application' –
62 | // will be applied by the user.
63 | project.getPlugins().apply(JavaBasePlugin.class);
64 |
65 | // Use 'OsDetectorPlugin' to select the platform the build runs on as default.
66 | project.getPlugins().apply(OsDetectorPlugin.class);
67 |
68 | JavaFXOptions javaFXOptions = project.getExtensions().create("javafx", JavaFXOptions.class,
69 | project.getExtensions().getByType(SourceSetContainer.class),
70 | project.getExtensions().getByType(OsDetector.class));
71 |
72 | // Register 'JavaFXComponentMetadataRule' to add variant information to all JavaFX modules.
73 | // Future JavaFX versions could publish this information using Gradle Metadata.
74 | for (JavaFXModule javaFXModule: JavaFXModule.values()) {
75 | project.getDependencies().getComponents().withModule(
76 | MAVEN_JAVAFX_ARTIFACT_GROUP_ID + ":" + javaFXModule.getArtifactName(),
77 | JavaFXComponentMetadataRule.class);
78 | }
79 |
80 | // Only set the default 'configuration' to 'implementation' when the 'java' plugin is applied.
81 | // Otherwise, it won't exist. (Note: 'java' is implicitly applied by 'application' or 'java-library'
82 | // and other Java-base plugins like Kotlin JVM)
83 | project.getPlugins().withId("java", p -> javaFXOptions.setConfiguration("implementation"));
84 |
85 |
86 | project.afterEvaluate(new Action() {
87 | @Override
88 | public void execute(Project project) {
89 | if (!project.getPlugins().hasPlugin("application") ||
90 | (project.getPlugins().hasPlugin("org.javamodularity.moduleplugin")) && project.getExtensions().findByName("modulename") != null) {
91 | return;
92 | }
93 |
94 | project.getTasks().named("run", JavaExec.class, new Action() {
95 | @Override
96 | public void execute(JavaExec task) {
97 | if (task.getMainModule().isPresent()) {
98 | return;
99 | }
100 | final var fxPlatform = javaFXOptions.getFxPlatform();
101 | final var fxModules = javaFXOptions.getFxModules();
102 | task.doFirst(a -> {
103 | putJavaFXJarsOnModulePathForClasspathApplication(task, fxPlatform, fxModules);
104 | });
105 | }
106 | });
107 |
108 | }
109 | });
110 |
111 | }
112 |
113 | /**
114 | * Gradle does currently not put anything on the --module-path if the application itself is executed from
115 | * the classpath. Hence, this patches the setup of Gradle's standard ':run' task to move all JavaFX Jars
116 | * from '-classpath' to '-module-path'. This functionality is only relevant for NON-MODULAR apps.
117 | */
118 | private static void putJavaFXJarsOnModulePathForClasspathApplication(JavaExec execTask, final Property platform, final SetProperty stringSetProperty) {
119 | FileCollection classpath = execTask.getClasspath();
120 |
121 | execTask.setClasspath(classpath.filter(jar -> !isJavaFXJar(jar, platform.get())));
122 | var modulePath = classpath.filter(jar -> isJavaFXJar(jar, platform.get()));
123 |
124 | execTask.getJvmArgumentProviders().add(() -> List.of(
125 | "--module-path", modulePath.getAsPath(),
126 | "--add-modules", String.join(",", stringSetProperty.get())
127 | ));
128 | }
129 |
130 | private static boolean isJavaFXJar(File jar, JavaFXPlatform platform) {
131 | return jar.isFile() &&
132 | Arrays.stream(JavaFXModule.values()).anyMatch(javaFXModule ->
133 | javaFXModule.compareJarFileName(platform, jar.getName()) ||
134 | javaFXModule.getModuleJarFileName().equals(jar.getName()));
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/org/openjfx/gradle/metadatarule/JavaFXComponentMetadataRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.metadatarule;
31 |
32 | import org.gradle.api.artifacts.CacheableRule;
33 | import org.gradle.api.artifacts.ComponentMetadataContext;
34 | import org.gradle.api.artifacts.ComponentMetadataDetails;
35 | import org.gradle.api.artifacts.ComponentMetadataRule;
36 | import org.gradle.api.model.ObjectFactory;
37 | import org.gradle.nativeplatform.MachineArchitecture;
38 | import org.gradle.nativeplatform.OperatingSystemFamily;
39 | import org.openjfx.gradle.JavaFXPlatform;
40 |
41 | import javax.inject.Inject;
42 |
43 | import static org.gradle.nativeplatform.MachineArchitecture.ARCHITECTURE_ATTRIBUTE;
44 | import static org.gradle.nativeplatform.OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE;
45 |
46 | /**
47 | *
48 | * Component Metadata RulesAdding variants for native jars
49 | *
50 | */
51 | @CacheableRule
52 | abstract public class JavaFXComponentMetadataRule implements ComponentMetadataRule {
53 |
54 | @Inject
55 | abstract protected ObjectFactory getObjects();
56 |
57 | @Override
58 | public void execute(ComponentMetadataContext context) {
59 | var details = context.getDetails();
60 |
61 | for (JavaFXPlatform javaFXPlatform : JavaFXPlatform.values()) {
62 | addJavaFXPlatformVariant(javaFXPlatform, details, "Compile", "compile");
63 | addJavaFXPlatformVariant(javaFXPlatform, details, "Runtime", "runtime");
64 | }
65 | }
66 |
67 | private void addJavaFXPlatformVariant(JavaFXPlatform javaFXPlatform, ComponentMetadataDetails details, String nameSuffix, String baseVariant) {
68 | var name = details.getId().getName();
69 | var version = details.getId().getVersion();
70 |
71 | // Use 'maybeAddVariant'. As long as the metadata is sourced from POM, 'compile' and 'runtime' exist.
72 | // These are used as base for the additional variants so that those variants have the same dependencies.
73 | // If future JavaFX versions should publish the variants directly with Gradle metadata, the rule will
74 | // have no effect on these future versions, as the variants will be named different.
75 | details.maybeAddVariant(javaFXPlatform.getClassifier() + nameSuffix, baseVariant, variant -> {
76 | variant.attributes(attributes -> {
77 | attributes.attribute(OPERATING_SYSTEM_ATTRIBUTE, getObjects().named(OperatingSystemFamily.class, javaFXPlatform.getOsFamily()));
78 | attributes.attribute(ARCHITECTURE_ATTRIBUTE, getObjects().named(MachineArchitecture.class, javaFXPlatform.getArch()));
79 | });
80 | variant.withFiles(files -> {
81 | files.removeAllFiles();
82 | files.addFile(name + "-" + version + "-" + javaFXPlatform.getClassifier() + ".jar");
83 | });
84 | });
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXModuleTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import org.gradle.api.GradleException;
33 | import org.junit.jupiter.api.Test;
34 |
35 | import java.util.List;
36 | import java.util.Optional;
37 |
38 | import static org.junit.jupiter.api.Assertions.assertEquals;
39 | import static org.junit.jupiter.api.Assertions.assertTrue;
40 | import static org.junit.jupiter.api.Assertions.fail;
41 |
42 | class JavaFXModuleTest {
43 |
44 | @Test
45 | void existingModuleName() {
46 | Optional javafxDependency = JavaFXModule.fromModuleName("javafx.base");
47 | assertTrue(javafxDependency.isPresent());
48 | assertEquals(JavaFXModule.BASE, javafxDependency.get());
49 | }
50 |
51 | @Test
52 | void nonExistingModuleName() {
53 | assertTrue(JavaFXModule.fromModuleName("javafx.unknown").isEmpty());
54 | }
55 |
56 | @Test
57 | void getModuleName() {
58 | assertEquals("javafx.base", JavaFXModule.BASE.getModuleName());
59 | }
60 |
61 | @Test
62 | void getArtifactName() {
63 | assertEquals("javafx-base", JavaFXModule.BASE.getArtifactName());
64 | }
65 |
66 | @Test
67 | void validateWithValidModules() {
68 | var moduleNames = List.of(JavaFXModule.CONTROLS.getModuleName(), JavaFXModule.WEB.getModuleName());
69 |
70 | JavaFXModule.validateModules(moduleNames);
71 | }
72 |
73 | @Test
74 | void validateWithInvalidModules() {
75 | var moduleNames = List.of("javafx.unknown", JavaFXModule.CONTROLS.getModuleName(), JavaFXModule.WEB.getModuleName());
76 |
77 | try {
78 | JavaFXModule.validateModules(moduleNames);
79 | fail("Validate Modules must throw GradleException.");
80 | } catch (GradleException e) {
81 | // expected
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | import org.gradle.testfixtures.ProjectBuilder;
33 | import org.gradle.testkit.runner.BuildResult;
34 | import org.gradle.testkit.runner.GradleRunner;
35 | import org.gradle.testkit.runner.TaskOutcome;
36 | import org.junit.jupiter.api.Assumptions;
37 | import org.junit.jupiter.api.Test;
38 |
39 | import java.io.File;
40 | import java.lang.management.ManagementFactory;
41 | import java.util.ArrayList;
42 | import java.util.Arrays;
43 | import java.util.List;
44 | import java.util.stream.Collectors;
45 |
46 | import static org.junit.jupiter.api.Assertions.assertEquals;
47 |
48 | abstract class JavaFXPluginSmokeTest {
49 |
50 | private static final String classifier;
51 |
52 | static {
53 | var p = ProjectBuilder.builder().build();
54 | p.getPlugins().apply(JavaFXPlugin.class);
55 | classifier = p.getExtensions().getByType(JavaFXOptions.class).getPlatform().getClassifier();
56 | }
57 |
58 | protected abstract String getGradleVersion();
59 |
60 | protected String modularApplicationRuntime() {
61 | return "modular-with-modularity-plugin.jar";
62 | }
63 |
64 | @Test
65 | void smokeTestModular() {
66 | var result = build(":modular:run");
67 |
68 | assertEquals(TaskOutcome.SUCCESS, result.task(":modular:run").getOutcome());
69 |
70 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar"), modulePath(result).get(0));
71 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar", "modular.jar"), modulePath(result).get(1));
72 |
73 | assertEquals(List.of(), compileClassPath(result));
74 | assertEquals(List.of(), runtimeClassPath(result));
75 | }
76 |
77 | @Test
78 | void smokeTestModularWithModularityPlugin() {
79 | Assumptions.assumeFalse(useConfigurationCache(), "modularity plugin does not support configuration cache");
80 | var result = build(":modular-with-modularity-plugin:run");
81 |
82 | assertEquals(TaskOutcome.SUCCESS, result.task(":modular-with-modularity-plugin:run").getOutcome());
83 |
84 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar"), modulePath(result).get(0));
85 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar", modularApplicationRuntime()), modulePath(result).get(1));
86 |
87 | assertEquals(List.of(), compileClassPath(result));
88 | assertEquals(List.of(), runtimeClassPath(result));
89 | }
90 |
91 | @Test
92 | void smokeTestNonModular() {
93 | var result = build(":non-modular:run");
94 |
95 | assertEquals(TaskOutcome.SUCCESS, result.task(":non-modular:run").getOutcome());
96 |
97 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar", "javafx-media-17-" + classifier + ".jar", "javafx-web-17-" + classifier + ".jar"), compileClassPath(result).get(0));
98 | assertEquals(List.of("main", "main"), runtimeClassPath(result).get(0));
99 | assertEquals(List.of("javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar", "javafx-media-17-" + classifier + ".jar", "javafx-web-17-" + classifier + ".jar"), modulePath(result).get(0));
100 | }
101 |
102 | @Test
103 | void smokeTestTransitive() {
104 | var result = build(":transitive:run");
105 |
106 | assertEquals(TaskOutcome.SUCCESS, result.task(":transitive:run").getOutcome());
107 |
108 | assertEquals(List.of("charts-17.1.41.jar", "javafx-base-17-" + classifier + ".jar", "javafx-controls-17-" + classifier + ".jar", "javafx-graphics-17-" + classifier + ".jar"), compileClassPath(result).get(0));
109 | assertEquals(List.of("charts-17.1.41.jar", "countries-17.0.29.jar", "heatmap-17.0.17.jar", "logback-classic-1.2.6.jar", "logback-core-1.2.6.jar", "main", "main", "slf4j-api-1.7.32.jar", "toolbox-17.0.45.jar", "toolboxfx-17.0.37.jar"), runtimeClassPath(result).get(0));
110 | assertEquals(List.of("javafx-base-17.0.6-" + classifier + ".jar", "javafx-controls-17.0.6-" + classifier + ".jar", "javafx-graphics-17.0.6-" + classifier + ".jar", "javafx-swing-17.0.6-" + classifier + ".jar"), modulePath(result).get(0));
111 | }
112 |
113 | @Test
114 | void smokeTestLocalSdk() {
115 | var result = build(":local-sdk:build"); // do not ':run', as it won't run on any platform
116 |
117 | assertEquals(TaskOutcome.SUCCESS, result.task(":local-sdk:build").getOutcome());
118 |
119 | assertEquals(List.of("javafx.base.jar", "javafx.controls.jar", "javafx.graphics.jar"), compileClassPath(result).get(0));
120 | assertEquals(List.of(), modulePath(result));
121 | }
122 |
123 | private static List> modulePath(BuildResult result) {
124 | return path(result, "--module-path ");
125 | }
126 |
127 | private static List> compileClassPath(BuildResult result) {
128 | return path(result, "-classpath ");
129 | }
130 |
131 | private static List> runtimeClassPath(BuildResult result) {
132 | return path(result, "-cp ");
133 | }
134 |
135 | private static List> path(BuildResult result, String pathArg) {
136 | // Parse classpath or module path from Gradle's '--debug' output.
137 | // The :compileJava and :run tasks log them on that logging level.
138 | return result.getOutput().lines().filter(l -> l.contains(pathArg)).map(l -> {
139 | int pathArgIndex = l.indexOf(pathArg) + pathArg.length();
140 | String pathString = l.substring(pathArgIndex, l.indexOf(" ", pathArgIndex));
141 | //recently gradle added an empty classpath instead of omitting it entirely which seems like the same thing?
142 | if (pathString.isBlank() || pathString.equals("\"\"")) {
143 | return List.of();
144 | }
145 | String[] path = pathString.split(System.getProperty("path.separator"));
146 | return Arrays.stream(path).map(jar -> new File(jar).getName()).sorted().collect(Collectors.toList());
147 | }).filter(p -> !p.isEmpty()).collect(Collectors.toList());
148 | }
149 |
150 | private BuildResult build(String task) {
151 | return GradleRunner.create()
152 | .withProjectDir(new File("test-project"))
153 | .withGradleVersion(getGradleVersion())
154 | .withPluginClasspath()
155 | .withDebug(ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("-agentlib:jdwp"))
156 | .withArguments(getGradleRunnerArguments(task))
157 | .build();
158 | }
159 |
160 | protected List getGradleRunnerArguments(String taskname) {
161 | //note that the tests are written around --debug, they will fail if you reduce logging
162 | final var args = new ArrayList(List.of("clean", taskname, "--stacktrace", "--debug"));
163 | if (useConfigurationCache()) {
164 | args.add("--configuration-cache");
165 | }
166 | return args;
167 |
168 | }
169 |
170 | protected boolean useConfigurationCache() {
171 | return false;
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle64.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 |
33 | class JavaFXPluginSmokeTestGradle64 extends JavaFXPluginSmokeTest {
34 |
35 | @Override
36 | protected String getGradleVersion() {
37 | return "6.4";
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle69.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle69 extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "6.9.4";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle76.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle76 extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "7.6.1";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle814.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle814 extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "8.14";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle814CC.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle814CC extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "8.14";
37 | }
38 |
39 | @Override
40 | protected boolean useConfigurationCache() {
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle83.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle83 extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "8.3";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle87.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle87 extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "8.7";
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTestGradle87CC.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle;
31 |
32 | class JavaFXPluginSmokeTestGradle87CC extends JavaFXPluginSmokeTest {
33 |
34 | @Override
35 | protected String getGradleVersion() {
36 | return "8.7";
37 | }
38 |
39 | @Override
40 | protected boolean useConfigurationCache() {
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test-project/build.gradle:
--------------------------------------------------------------------------------
1 | import org.gradle.util.GradleVersion
2 |
3 | ext.gradleModuleSupport = GradleVersion.current() >= GradleVersion.version("6.4")
4 |
5 | subprojects {
6 | apply plugin: 'java'
7 |
8 | java {
9 | sourceCompatibility = JavaVersion.VERSION_11
10 | targetCompatibility = JavaVersion.VERSION_11
11 | }
12 | }
--------------------------------------------------------------------------------
/test-project/local-sdk/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'org.openjfx.javafxplugin'
4 | }
5 |
6 | application {
7 | if (gradleModuleSupport) {
8 | mainClass = 'org.openjfx.gradle.javafx.test.Main'
9 | } else {
10 | mainClassName = 'org.openjfx.gradle.javafx.test.Main'
11 | }
12 | }
13 |
14 | javafx {
15 | modules = ['javafx.controls']
16 | sdk = "javafx-sdk-17.0.8"
17 | }
18 |
--------------------------------------------------------------------------------
/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.base.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openjfx/javafx-gradle-plugin/9f43de5cd4628e44f70c66659011588e06e5f081/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.base.jar
--------------------------------------------------------------------------------
/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.controls.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openjfx/javafx-gradle-plugin/9f43de5cd4628e44f70c66659011588e06e5f081/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.controls.jar
--------------------------------------------------------------------------------
/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.graphics.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openjfx/javafx-gradle-plugin/9f43de5cd4628e44f70c66659011588e06e5f081/test-project/local-sdk/javafx-sdk-17.0.8/lib/javafx.graphics.jar
--------------------------------------------------------------------------------
/test-project/local-sdk/src/main/java/org/openjfx/gradle/javafx/test/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.javafx.test;
31 |
32 | import javafx.application.Application;
33 | import javafx.scene.Scene;
34 | import javafx.scene.control.Label;
35 | import javafx.scene.layout.StackPane;
36 | import javafx.stage.Stage;
37 |
38 | public class Main extends Application {
39 |
40 | @Override
41 | public void start(Stage primaryStage) {
42 | StackPane root = new StackPane(new Label("Hello World!"));
43 |
44 | Scene scene = new Scene(root, 800, 600);
45 |
46 | primaryStage.setScene(scene);
47 | primaryStage.show();
48 |
49 | new Thread(() -> {
50 | try {
51 | Thread.sleep(500);
52 | } catch (InterruptedException e) {
53 | throw new RuntimeException("Should not happen!");
54 | }
55 |
56 | System.exit(0);
57 | }).start();
58 | }
59 | }
--------------------------------------------------------------------------------
/test-project/modular-with-modularity-plugin/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'org.openjfx.javafxplugin'
4 | id 'org.javamodularity.moduleplugin' version '1.8.12'
5 | }
6 |
7 | repositories.mavenCentral()
8 |
9 | if (gradleModuleSupport) java.modularity.inferModulePath = false
10 |
11 | application {
12 | if (gradleModuleSupport) {
13 | mainModule = 'org.openjfx.gradle.javafx.test'
14 | mainClass = 'org.openjfx.gradle.javafx.test.Main'
15 | } else {
16 | mainClassName = 'org.openjfx.gradle.javafx.test.Main'
17 | }
18 | }
19 |
20 | javafx {
21 | modules = ['javafx.controls']
22 | }
23 |
--------------------------------------------------------------------------------
/test-project/modular-with-modularity-plugin/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | module org.openjfx.gradle.javafx.test {
31 | requires javafx.controls;
32 |
33 | exports org.openjfx.gradle.javafx.test;
34 | }
--------------------------------------------------------------------------------
/test-project/modular-with-modularity-plugin/src/main/java/org/openjfx/gradle/javafx/test/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.javafx.test;
31 |
32 | import javafx.application.Application;
33 | import javafx.scene.Scene;
34 | import javafx.scene.control.Label;
35 | import javafx.scene.layout.StackPane;
36 | import javafx.stage.Stage;
37 |
38 | public class Main extends Application {
39 |
40 | @Override
41 | public void start(Stage primaryStage) {
42 | StackPane root = new StackPane(new Label("Hello World!"));
43 |
44 | Scene scene = new Scene(root, 800, 600);
45 |
46 | primaryStage.setScene(scene);
47 | primaryStage.show();
48 |
49 | new Thread(() -> {
50 | try {
51 | Thread.sleep(500);
52 | } catch (InterruptedException e) {
53 | throw new RuntimeException("Should not happen!");
54 | }
55 |
56 | System.exit(0);
57 | }).start();
58 | }
59 | }
--------------------------------------------------------------------------------
/test-project/modular/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'org.openjfx.javafxplugin'
4 | }
5 |
6 | repositories.mavenCentral()
7 |
8 | if (gradleModuleSupport) java.modularity.inferModulePath = true
9 |
10 | application {
11 | if (gradleModuleSupport) {
12 | mainModule = 'org.openjfx.gradle.javafx.test'
13 | mainClass = 'org.openjfx.gradle.javafx.test.Main'
14 | } else {
15 | mainClassName = 'org.openjfx.gradle.javafx.test.Main'
16 | }
17 | }
18 |
19 | javafx {
20 | modules = ['javafx.controls']
21 | }
22 |
--------------------------------------------------------------------------------
/test-project/modular/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | module org.openjfx.gradle.javafx.test {
31 | requires javafx.controls;
32 |
33 | exports org.openjfx.gradle.javafx.test;
34 | }
--------------------------------------------------------------------------------
/test-project/modular/src/main/java/org/openjfx/gradle/javafx/test/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.javafx.test;
31 |
32 | import javafx.application.Application;
33 | import javafx.scene.Scene;
34 | import javafx.scene.control.Label;
35 | import javafx.scene.layout.StackPane;
36 | import javafx.stage.Stage;
37 |
38 | public class Main extends Application {
39 |
40 | @Override
41 | public void start(Stage primaryStage) {
42 | StackPane root = new StackPane(new Label("Hello World!"));
43 |
44 | Scene scene = new Scene(root, 800, 600);
45 |
46 | primaryStage.setScene(scene);
47 | primaryStage.show();
48 |
49 | new Thread(() -> {
50 | try {
51 | Thread.sleep(500);
52 | } catch (InterruptedException e) {
53 | throw new RuntimeException("Should not happen!");
54 | }
55 |
56 | System.exit(0);
57 | }).start();
58 | }
59 | }
--------------------------------------------------------------------------------
/test-project/non-modular/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'org.openjfx.javafxplugin' version '0.0.14'
4 | id 'org.javamodularity.moduleplugin' version '1.8.12'
5 | }
6 |
7 | repositories.mavenCentral()
8 |
9 | application {
10 | if (gradleModuleSupport) {
11 | mainClass = 'org.openjfx.gradle.javafx.test.Main'
12 | } else {
13 | mainClassName = 'org.openjfx.gradle.javafx.test.Main'
14 | }
15 | }
16 |
17 | javafx {
18 | modules = [ 'javafx.controls', 'javafx.web' ]
19 | }
20 |
--------------------------------------------------------------------------------
/test-project/non-modular/src/main/java/org/openjfx/gradle/javafx/test/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.javafx.test;
31 |
32 | import javafx.application.Application;
33 | import javafx.scene.Scene;
34 | import javafx.scene.control.Label;
35 | import javafx.scene.layout.StackPane;
36 | import javafx.stage.Stage;
37 |
38 | public class Main extends Application {
39 |
40 | @Override
41 | public void start(Stage primaryStage) {
42 | StackPane root = new StackPane(new Label("Hello World!"));
43 |
44 | Scene scene = new Scene(root, 800, 600);
45 |
46 | primaryStage.setScene(scene);
47 | primaryStage.show();
48 |
49 | new Thread(() -> {
50 | try {
51 | Thread.sleep(500);
52 | } catch (InterruptedException e) {
53 | throw new RuntimeException("Should not happen!");
54 | }
55 |
56 | System.exit(0);
57 | }).start();
58 | }
59 | }
--------------------------------------------------------------------------------
/test-project/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'javafxplugintests'
2 |
3 | include 'local-sdk'
4 | include 'modular'
5 | include 'modular-with-modularity-plugin'
6 | include 'non-modular'
7 | include 'transitive'
--------------------------------------------------------------------------------
/test-project/transitive/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'org.openjfx.javafxplugin'
4 | }
5 |
6 | repositories.mavenCentral {
7 | metadataSources {
8 | // Gradle Metadata is broken for 'eu.hansolo.fx:charts:17.1.41'. It's fixed in '17.1.51',
9 | // but that version depends on JavaFX 20, and we want to stick with 17 for now in the test.
10 | mavenPom()
11 | ignoreGradleMetadataRedirection()
12 | }
13 | }
14 |
15 | application {
16 | if (gradleModuleSupport) {
17 | mainClass = 'org.openjfx.gradle.javafx.test.Main'
18 | } else {
19 | mainClassName = 'org.openjfx.gradle.javafx.test.Main'
20 | }
21 | }
22 |
23 | javafx {
24 | version = '17'
25 | modules = [ 'javafx.controls' ]
26 | }
27 |
28 | dependencies {
29 | // has runtime dependency on javafx-base-17.0.6, javafx-controls-17.0.6, javafx-graphics-17.0.6, javafx-swing-17.0.6
30 | implementation 'eu.hansolo.fx:charts:17.1.41'
31 | }
32 |
--------------------------------------------------------------------------------
/test-project/transitive/src/main/java/org/openjfx/gradle/javafx/test/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023, Gluon
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * * Neither the name of the copyright holder nor the names of its
16 | * contributors may be used to endorse or promote products derived from
17 | * this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | package org.openjfx.gradle.javafx.test;
31 |
32 | import javafx.application.Application;
33 | import javafx.scene.Scene;
34 | import javafx.scene.control.Label;
35 | import javafx.scene.layout.StackPane;
36 | import javafx.stage.Stage;
37 |
38 | public class Main extends Application {
39 |
40 | @Override
41 | public void start(Stage primaryStage) {
42 | StackPane root = new StackPane(new Label("Hello World!"));
43 |
44 | Scene scene = new Scene(root, 800, 600);
45 |
46 | primaryStage.setScene(scene);
47 | primaryStage.show();
48 |
49 | new Thread(() -> {
50 | try {
51 | Thread.sleep(500);
52 | } catch (InterruptedException e) {
53 | throw new RuntimeException("Should not happen!");
54 | }
55 |
56 | System.exit(0);
57 | }).start();
58 | }
59 | }
--------------------------------------------------------------------------------