├── .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 | [![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/org/openjfx/javafxplugin/org.openjfx.javafxplugin.gradle.plugin/maven-metadata.xml.svg?label=Gradle%20Plugin)](https://plugins.gradle.org/plugin/org.openjfx.javafxplugin) 6 | ![Github Actions](https://github.com/openjfx/javafx-gradle-plugin/actions/workflows/build.yml/badge.svg) 7 | [![BSD-3 license](https://img.shields.io/badge/license-BSD--3-%230778B9.svg)](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 | } --------------------------------------------------------------------------------