├── .editorconfig ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── appveyor.yml ├── build.gradle ├── config └── checkstyle │ ├── checkstyle.xml │ └── license.header ├── examples ├── additional-application-files │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── additional-files │ │ └── dummy.txt │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── additional-bundler-files │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── deploy │ │ ├── bundlers │ │ │ └── win-exe.image │ │ │ │ └── license.rtf │ │ └── package │ │ │ └── windows │ │ │ └── additional-bundler-files.iss │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── adjusted-launcher-icon │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── deploy │ │ └── package │ │ │ └── windows │ │ │ └── adjusted-launcher-icon.ico │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── debian-installer-with-license │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── additionalFiles │ │ └── LICENSE │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── file-associations │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ ├── deploy │ │ └── file-associations.ico │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── javafx-proguard-gradle │ ├── README.md │ ├── build.gradle │ ├── proguard.conf │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── zenjava │ │ │ └── test │ │ │ └── javafx_and_proguard │ │ │ ├── HelloController.java │ │ │ └── MainApp.java │ │ └── resources │ │ ├── com │ │ └── zenjava │ │ │ └── test │ │ │ └── javafx_and_proguard │ │ │ └── HelloController.fxml │ │ ├── images │ │ └── background.jpg │ │ ├── log4j.xml │ │ └── styles │ │ └── styles.css ├── jnlp-minimal │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── minimal-setup-jfxjar │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── minimal-setup-jfxnative │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── minimal-setup-without-bundled-jre │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java ├── multi-module-project │ └── .gitkeep ├── secondary-native-launchers │ └── .gitkeep ├── simpler-application-name │ ├── README.md │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── dynamicfiles │ │ └── projects │ │ └── gradle │ │ └── example │ │ └── MainClass.java └── windows-installer-with-license │ ├── README.md │ ├── build.gradle │ └── src │ └── main │ ├── additionalFiles │ └── license.rtf │ └── java │ └── de │ └── dynamicfiles │ └── projects │ └── gradle │ └── example │ └── MainClass.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── src ├── main │ ├── java │ │ └── de │ │ │ └── dynamicfiles │ │ │ └── projects │ │ │ └── gradle │ │ │ └── plugins │ │ │ └── javafx │ │ │ ├── JavaFXGradlePlugin.java │ │ │ ├── JavaFXGradlePluginExtension.java │ │ │ ├── dto │ │ │ ├── FileAssociation.java │ │ │ └── NativeLauncher.java │ │ │ └── tasks │ │ │ ├── JfxGenerateKeystoreTask.java │ │ │ ├── JfxJarTask.java │ │ │ ├── JfxListBundlersTask.java │ │ │ ├── JfxNativeTask.java │ │ │ ├── JfxRunTask.java │ │ │ ├── internal │ │ │ ├── JavaDetectionTools.java │ │ │ ├── MonkeyPatcher.java │ │ │ ├── ParameterMapEntries.java │ │ │ └── Workarounds.java │ │ │ └── workers │ │ │ ├── JfxAbstractWorker.java │ │ │ ├── JfxGenerateKeystoreWorker.java │ │ │ ├── JfxJarWorker.java │ │ │ ├── JfxListBundlersWorker.java │ │ │ ├── JfxNativeWorker.java │ │ │ └── JfxRunWorker.java │ └── resources │ │ └── META-INF │ │ └── gradle-plugins │ │ └── javafx-gradle-plugin.properties └── test │ └── java │ └── de │ └── dynamicfiles │ └── projects │ └── gradle │ └── plugins │ └── javafx │ └── tests │ ├── exampleprojects │ ├── AdditionalApplicationFiles.java │ ├── AdditionalBundlerFiles.java │ ├── ExampleProjectTest.java │ ├── JavaFXProguardGradleExample.java │ ├── MinimalProjectJfxJar.java │ ├── MinimalProjectJfxNative.java │ └── MinimalProjectWithoutJre.java │ └── functional │ └── SimpleApply.java └── version.gradle /.editorconfig: -------------------------------------------------------------------------------- 1 | # this is the main configuration file 2 | root = true 3 | 4 | # unix-style line-endings with empty line ending 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | charset = utf-8 9 | 10 | # indent is spaces (4 spaces = 1 tab) 11 | [*.java] 12 | indent_style = space 13 | indent_size = 4 14 | 15 | # don't touch license-file 16 | [config/checkstyle/license.header] 17 | insert_final_newline = false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle 2 | /.nb-gradle 3 | build 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | matrix: 4 | include: 5 | ## kept in sync with javafx-maven-plugin for easier comparision 6 | ## https://docs.travis-ci.com/user/reference/trusty/ 7 | - os: linux 8 | sudo: false 9 | dist: trusty 10 | jdk: oraclejdk8 11 | install: true 12 | env: FAILURES_ALLOWED=false 13 | addons: 14 | apt: 15 | packages: 16 | ## RPM 17 | - rpm 18 | ## DEB 19 | - fakeroot 20 | ## OpenJDK should work too, but TravisCI has no up2date Ubuntu-Image, makes it impossible to install OpenJFX 21 | - os: linux 22 | sudo: false 23 | dist: trusty 24 | jdk: oraclejdk9 25 | install: true 26 | env: FAILURES_ALLOWED=false 27 | addons: 28 | apt: 29 | packages: 30 | ## RPM 31 | - rpm 32 | ## DEB 33 | - fakeroot 34 | ## has older Maven 35 | - os: linux 36 | sudo: false 37 | dist: precise 38 | jdk: oraclejdk8 39 | env: FAILURES_ALLOWED=false 40 | addons: 41 | apt: 42 | packages: 43 | ## RPM 44 | - rpm 45 | ## DEB 46 | - fakeroot 47 | ## use different OSX versions 48 | ## OS X 10.11 49 | - os: osx 50 | osx_image: xcode8 51 | env: FAILURES_ALLOWED=false 52 | ## OS X 10.12 53 | - os: osx 54 | osx_image: xcode8.3 55 | env: FAILURES_ALLOWED=false 56 | ## OS X 10.12 57 | - os: osx 58 | osx_image: xcode9.2 59 | env: FAILURES_ALLOWED=false 60 | allow_failures: 61 | - env: FAILURES_ALLOWED=true 62 | 63 | # http://stackoverflow.com/questions/35128777/travis-ci-build-failed#comment58070003_35153221 64 | before_install: 65 | - chmod +x gradlew 66 | 67 | script: 68 | - ./gradlew clean install 69 | - ./gradlew check 70 | 71 | branches: 72 | only: 73 | - master 74 | - newyear2018release 75 | 76 | notifications: 77 | email: false 78 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Release Notes 2 | ============= 3 | 4 | # Version 8.8.2 (09-February-2017) 5 | 6 | Bugfixes: 7 | * fixed `launcherArguments` of secondary launchers not being set correctly (fixes issue #55) 8 | 9 | 10 | 11 | # Version 8.8.1 (06-February-2017) 12 | 13 | Bugfixes: 14 | * fixed wrong calculated classpath when scanning the lib-folder was activated 15 | 16 | 17 | 18 | # Version 8.8.0 (05-February-2017) 19 | 20 | New: 21 | * `nativeReleaseVersion` will now get sanitized, anything than numbers and dots are removed, this ensures compatibility with the used bundler toolsets 22 | * when using `noBlobSigning = true` (which will get dropped with JDK9) the `jarsigner` executable will be used, but it was lacking proper customization, therefor a new property was introduced `additionalJarsignerParameters` which will be appended to all other stuff on the jarsigner-command 23 | * added ability to fail the build on errors while bundling, just set `failOnError = true` inside the jfx-block 24 | * when having not specified any bundler, it now is possible to remove that JNLP-warning regarding "No OutFile Specificed", which makes that bundler being skipped, just set `skipJNLP = true` inside the jfx-block 25 | * added property to skip `nativeReleaseVersion` rewriting, just set `skipNativeVersionNumberSanitizing = true` inside the jfx-block 26 | * added `skipCopyingDependencies` to make it possible to NOT copying dependencies, but they are added to the classpath inside the manifest like normal 27 | * added `fixedManifestClasspath` for setting the classpath-entry inside the generated manifest-file in the main jfx-jar, this is already possible for secondary launchers by setting `classpath` within the configuration-block of the secondary launcher 28 | * added `useLibFolderContentForManifestClasspath` for creating the manifest-entriy for the classpath, depending on the content of the lib-folder, makes it possible to have files not being inside dependencies being present there (which got copied beforehand) 29 | 30 | Changes: 31 | * reimplemented `additionalBundlerResources`, now searching for folders with the name of the used bundler, makes it possible to adjust nearly all bundlers now (for Mac a special replacement-class was created, as the default one did not provide any way to add more files) 32 | 33 | Enhancements: 34 | * updated all example-projects to use a different variable-name of the "current" plugin-version (fixes issue #40) 35 | * added warning about slow performance (even on SSD) when having ext4/btrfs filesystems using "deb"-bundler (fixes issue #41) 36 | * added warning about missing "jnlp.outfile"-property inside bundleArguments when using JNLP-bundler (from issue #42) 37 | * added ability to change name of the lib-folder by setting `libFolderName` 38 | 39 | Bugfixes: 40 | * added support for Gradle 3.3 (fixes issue #52) 41 | 42 | 43 | 44 | # Version 8.7.0 (09-September-2016) 45 | 46 | New: 47 | * added `checkForAbsolutePaths`-property to enable absolute paths for all path-properties (it defaults to `false` to behave like before) 48 | * added `additionalBundlerResources` for being able to have additional files available to the used bundler 49 | * added feature for copying additionalAppResources to `build/jfx/app` when calling `jfxJar` and `jfxRun`, making it possible to have all that files available (like native files being required to not reside in the jar-files) by setting `copyAdditionalAppResourcesToJar = true` (issue #39) 50 | 51 | Bugfixes: 52 | * made it possible to specify absolute paths for all path-properties, fixes issue #36 53 | * reverted the idea of registering the real tasks after project-evaluation, only add ant-javafx.jar after project-evaluation (fixes issue #31) 54 | * adjusted CI-files for AppVeyor and TravisCI to handle functional tests 55 | * fixed possible file-handler leak (unreported) 56 | 57 | Changes: 58 | * removed the `skipDaemonModeCheck`-property, please remove this from your configuration/buildscript 59 | 60 | Enhancements: 61 | * implemented some functional tests, mostly using the example-projects as test-projects (running against Gradle 2.10 and Gradle 3.0) 62 | * added example project: windows installer with license 63 | * added example project: debian installer with license 64 | * added example project: adjusted launcher-icon 65 | * added example project: additional bundler-files 66 | * extracted plugin-version into separated file to have example-projects working at their place without having the need to adjust these version-numbers on every release 67 | * refactored a bit to have cleaner code 68 | 69 | 70 | 71 | # Version 8.6.0 (31-August-2016) 72 | 73 | New: 74 | * added `alternativePathToJarFile`-property to specify the jar-file which gets used for javafx-jar-transformation 75 | * added `usePatchedJFXAntLib`-property to disable gradle daemon workaround of the JDK-bug (which might be required when patching does result in crashing the JVM) 76 | * added `useEnvironmentRelativeExecutables`-property to change the executables being used from the JDK instead of environment-relative (which could differ due to multiple local java-installations) 77 | * added possibility to adjust java-command used for `jfxRun`-task: it is now possible to pass parameters to your jfx-application 78 | * added possibility to adjust java-command used for `jfxRun`-task: it is now possible to pass parameters to the java-executable, e.g. to specify some javassist-module or other JVM-related stuff (like Xmx or other funny things) 79 | 80 | Bugfixes: 81 | * fixed issue #29 and #30 regarding stdout/stderr not printed when Gradle is in daemon mode (which is default for Gradle 3 now) 82 | * fixed issue #12 regarding gradle daemon mode: **IT IS NOW SUPPORTED** 83 | 84 | Changes: 85 | * removed the usage of `skipDaemonModeCheck`-property, please remove this from your configuration/buildscript (will be removed in the next minor-release) 86 | * the javafx-gradle-plugin now requires ASM being present on classpath of the buildscript for being able to work around the JDK-bug (https://bugs.openjdk.java.net/browse/JDK-8148717) 87 | 88 | Enhancements: 89 | * fixed issue #26 by providing a way to specify jar-file used for javapackager 90 | * updated proguard example using new `alternativePathToJarFile`-property 91 | * updated README.md to show minimal setup and other stuff 92 | 93 | 94 | 95 | # Version 8.5.2 (31-July-2016) 96 | 97 | Bugfixes: 98 | * fixed issue #24 regarding NullPointerException inside workaround (I'm very sorry about that, thanks to @AustinShalit for finding this) 99 | 100 | **Note:** 101 | There won't be any [GString](http://docs.groovy-lang.org/latest/html/api/groovy/lang/GString.html)-support, please use `toString()` inside your buildscript 102 | 103 | Another note: I know, dependency-filtering is not yet implemented, but as this is a rather unused feature, I will take the time ;) 104 | 105 | 106 | 107 | # Version 8.5.1 (29-June-2016) 108 | 109 | New: 110 | * added new property to skip workaround for gradle daemon mode (which causes problems with the runtime-folder, see issue #12 for more information), this makes it now possible to create native builds within the IDE (at least once) 111 | 112 | Bugfixes: 113 | * fixed some classloader-problem when using javafx-gradle-plugin in combination with Netbeans IDE having netbeans-gradle-plugin installed *(I'm very sorry about this, don't know why this wasn't detected by me before)* 114 | * updated workaround-detection for creating native bundles without JRE, because [it got fixed by latest Oracle JDK 1.8.0u92](http://www.oracle.com/technetwork/java/javase/2col/8u92-bugfixes-2949473.html) 115 | 116 | Enhancements: 117 | * made it possible to specify file-association icon as [String](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html), [File](http://docs.oracle.com/javase/8/docs/api/java/io/File.html) or [Path](http://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html) 118 | * changed the way for adding `ant-javafx.jar` to the classloaders (by using more stuff provided by the gradle-api) 119 | 120 | Migrated from javafx-maven-plugin: 121 | * (bugfix) added workaround for native linux launcher inside native linux installer bundle (DEB and RPM) not working, see issue [#205](https://github.com/javafx-maven-plugin/javafx-maven-plugin/issues/205) for more details on this (it's a come-back of the [issue 124](https://github.com/javafx-maven-plugin/javafx-maven-plugin/issues/124)) 122 | * (new) added ability to write and use custom bundlers! This makes it possible to customize the work which is required for your bundling-process. 123 | * (new) added new property to disable "native linux launcher inside native linux installer"-fix `skipNativeLauncherWorkaround205 = true` 124 | * (improvement) moved workarounds and workaround-detection into its own class (makes it a bit easier to concentrate on the main work inside JfxNativeTask) 125 | 126 | **Note:** 127 | There won't be any [GString](http://docs.groovy-lang.org/latest/html/api/groovy/lang/GString.html)-support, please use `toString()` inside your buildscript 128 | 129 | Another note: I know, dependency-filtering is not yet implemented, but as this is a rather unused feature, I will take the time ;) 130 | 131 | 132 | 133 | # Version 8.4.1 (15-Mar-2016) 134 | 135 | Bugfixes: 136 | * copy dependencies with runtime-scope (fixes #15) 137 | 138 | 139 | 140 | # Version 8.4.0 (11-Mar-2016) 141 | 142 | New: 143 | * introduced `jfxRun` task 144 | * introduced `jfxGenerateKeyStore` task 145 | * when creating JNLP-files, your can now choose between Blob Signing (which was introduced since JavaFX but seems has never worked, and will be removed from Java 9) or normal signing done by `jarsigner` by providing the new proverty `noBlobSigning: true` 146 | 147 | Improvement: 148 | * added appveyor for building javafx-gradle-plugin on windows 149 | 150 | Starting with this release I will keep the [javafx-gradle-plugin](https://github.com/FibreFoX/javafx-gradle-plugin) and the [javafx-maven-plugin](https://github.com/javafx-maven-plugin/javafx-maven-plugin) in sync. This means, that you can compare the features of each plugin by comparing its major- and minor-version-number, I'm using [semantic versioning v2](http://semver.org/spec/v2.0.0.html). 151 | 152 | Next thing will be to create some tests and example-projects. 153 | 154 | 155 | 156 | # Version 1.3 (08-Mar-2016) 157 | 158 | Bugfixes: 159 | * replace backslash with normal slash within JNLP-files 160 | * add signing-feature for bundler with ID "jnlp" (by setting `"jnlp.allPermisions": true` inside bundleArguments) 161 | * fixed size-attributes within JNLP-files when using bundler with ID "jnlp" and requesting to sign the jars 162 | 163 | Next versions will be in sync with the javafx-maven-plugin, mostly to have a better visual sign what feature-set exists. This means to me, that I still have to do some work ;) 164 | 165 | 166 | 167 | # Version 1.2 (10-Feb-2016) 168 | 169 | New: 170 | * added workaround for issue #12 regarding [file descriptor leak inside the JDK starting from 1.8.0_60](https://bugs.openjdk.java.net/browse/JDK-8148717) 171 | 172 | As there seems to be no good way for having something like maven-invoker-plugin (which is used for the javafx-maven-plugin), I still need to find a nice way having buildable example-projects. 173 | 174 | 175 | 176 | # Version 1.1 (28-Jan-2016) 177 | 178 | Bugfixes: 179 | * fixed project-relative path-problems mostly regarding multi-module projects 180 | 181 | New: 182 | * added support for gradle daemon-mode 183 | 184 | Knowh bugs: 185 | * on windows: when calling task jfxNative you can't call task clean, because there is a possible file descriptor leak (see issue #12) 186 | 187 | There will be some examples with the next updates/releases, but this is a spare-time project so please just try it out, not yet recommended for production. 188 | 189 | 190 | 191 | # Version 1.0 (16-Jan-2016) Initial Release 192 | 193 | This is the very first release of my javafx-gradle-plugin, and my first official gradle-plugin too. 194 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Help me to make a better tool 2 | 3 | ## By creating issue-tickets 4 | 5 | When you think you found a bug, please check the issue-tracker at github first, if it isn't already reported. If you are unsure about having the same bug, don't hesitate to create a new issue-ticket, I will inform you about via comment or closing. 6 | 7 | 8 | ## By creating patches, features or pull-requests 9 | 10 | When you managed to find some time in creating a patch or implemented a new feature, please create small pull-requests. Having to merge a pull-request with different fixes or several new features is no easy task and won't be accepted (exceptions of this may occur when having similar small fixes). 11 | 12 | 13 | ## Some words about code-formatters and comments 14 | 15 | I love code-formatters, but until I have strict requirements for this project (I don't have them currently), please **do not** apply your formatter over the whole code, just on your changes should be enough. It shortens the time to check pull-requests for the change you really made (and not making the code look worse than it is). 16 | 17 | If there are some comments you find irritating or confusing (or even being wrong), just create a pull-request to adjust these parts. 18 | 19 | 20 | ## Inform others about us 21 | 22 | This project lives from the usage by others, show it to some collegues, use it in your spare-time-projects and feel free to spread this project all over the world. Every move to keep this project alive and kicking is very welcome. 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/FibreFoX/javafx-gradle-plugin.svg?branch=master)](https://travis-ci.org/FibreFoX/javafx-gradle-plugin) 2 | [![Build status](https://ci.appveyor.com/api/projects/status/19tkbde1wrw8mc8h/branch/master?svg=true)](https://ci.appveyor.com/project/FibreFoX/javafx-gradle-plugin/branch/master) 3 | [![Maven Central](https://img.shields.io/maven-central/v/de.dynamicfiles.projects.gradle.plugins/javafx-gradle-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/de.dynamicfiles.projects.gradle.plugins/javafx-gradle-plugin) 4 | 5 | 6 | JavaFX-Gradle-Plugin 7 | ==================== 8 | 9 | Using javafx-gradle-plugin enhances your build-script with `javapackager`-power. No more using Apache Ant-calls, because this gradle-plugin wraps all calls and introduces workarounds and fixes for not-yet-fixed JDK-bugs. This gradle-plugin is a convenient-wrapper for the javapackger, so you have to [visit the official documentation](https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html#A1324980) to know about the requirements on each operating-system. 10 | 11 | **Using OpenJDK?** Please make sure you have **OpenJFX** installed too, as the required JavaFX-parts are separated. 12 | 13 | 14 | **Using Maven?** Not problem, just [switch to the github-project of the javafx-maven-plugin](https://github.com/javafx-maven-plugin/javafx-maven-plugin). 15 | 16 | 17 | 18 | Why does this gradle-plugin exist? 19 | ================================== 20 | 21 | In the need of some equivalent of the [javafx-maven-plugin](https://github.com/javafx-maven-plugin/javafx-maven-plugin) just for gradle, this project was born. A lot of you might have used the [`javafx-gradle`-plugin from Danno Ferrin](https://bitbucket.org/shemnon/javafx-gradle/), but he decided [to not continue](https://bitbucket.org/shemnon/javafx-gradle/issues/47/adding-manifest-attribute-javafx#comment-24360784) that project. 22 | 23 | 24 | 25 | Requirements 26 | ============ 27 | * Gradle 2.10 and above (works on Gradle 3 too) 28 | * Java Developer Kit 8 with at least Update 40 29 | 30 | 31 | 32 | OS-specific requirements 33 | ======================== 34 | * (Windows) EXE installers: Inno Setup 35 | * (Windows) MSI installers: WiX (at least version 3.7) 36 | * (Linux) DEB installers: dpkg-deb 37 | * (Linux) RPM installers: rpmbuild 38 | * (Mac) DMG installers: hdiutil 39 | * (Mac) PKG installers: pkgbuild 40 | 41 | 42 | 43 | Example `build.gradle` 44 | ====================== 45 | 46 | Please adjust your parameters accordingly: 47 | 48 | ```groovy 49 | buildscript { 50 | dependencies { 51 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2' 52 | } 53 | 54 | repositories { 55 | mavenLocal() 56 | mavenCentral() 57 | } 58 | } 59 | 60 | apply plugin: 'java' 61 | 62 | repositories { 63 | mavenLocal() 64 | mavenCentral() 65 | } 66 | 67 | dependencies{ 68 | // this dependency is only required when using UserJvmOptionsService 69 | // when using Oracle JDK 70 | // compile files("${System.properties['java.home']}/../lib/packager.jar") 71 | // when using OpenJFX (Ubuntu), please adjust accordingly 72 | // compile files("/usr/share/java/openjfx/lib/packager.jar") 73 | } 74 | 75 | apply plugin: 'javafx-gradle-plugin' 76 | 77 | // these values are the examples and defaults 78 | // you won't need them all 79 | 80 | // configure javafx-gradle-plugin 81 | // for all available settings please look at the class "JavaFXGradlePluginExtension" 82 | jfx { 83 | verbose = true 84 | mainClass = "com.something.cool.MainApp" 85 | jfxAppOutputDir = "build/jfx/app" 86 | jfxMainAppJarName = "project-jfx.jar" 87 | deployDir = "src/main/deploy" 88 | useEnvironmentRelativeExecutables = true 89 | libFolderName = "lib" 90 | 91 | // gradle jfxJar 92 | css2bin = false 93 | preLoader = null // String 94 | updateExistingJar = false 95 | allPermissions = false 96 | manifestAttributes = null // Map 97 | addPackagerJar = true 98 | copyAdditionalAppResourcesToJar = false 99 | skipCopyingDependencies = false 100 | useLibFolderContentForManifestClasspath = false 101 | fixedManifestClasspath = null 102 | 103 | // gradle jfxNative 104 | identifier = null // String - setting this for windows-bundlers makes it possible to generate upgradeable installers (using same GUID) 105 | vendor = "some serious business corp." 106 | nativeOutputDir = "build/jfx/native" 107 | bundler = "ALL" // set this to some specific, if your don't want all bundlers running, examples "windows.app", "jnlp", ... 108 | jvmProperties = null // Map 109 | jvmArgs = null // List 110 | userJvmArgs = null // Map 111 | launcherArguments = null // List 112 | nativeReleaseVersion = "1.0" 113 | needShortcut = false 114 | needMenu = false 115 | bundleArguments = [ 116 | // dont bundle JRE (not recommended, but increases build-size/-speed) 117 | runtime: null 118 | ] 119 | appName = "project" // this is used for files below "src/main/deploy", e.g. "src/main/deploy/package/windows/project.ico" 120 | additionalBundlerResources = null // path to some additional resources for the bundlers when creating application-bundle 121 | additionalAppResources = null // path to some additional resources when creating application-bundle 122 | secondaryLaunchers = [[appName:"somethingDifferent"], [appName:"somethingDifferent2"]] 123 | fileAssociations = null // List> 124 | noBlobSigning = false // when using bundler "jnlp", you can choose to NOT use blob signing 125 | customBundlers = null // List 126 | failOnError = false 127 | onlyCustomBundlers = false 128 | skipJNLP = false 129 | skipNativeVersionNumberSanitizing = false // anything than numbers or dots are removed 130 | additionalJarsignerParameters = null // List 131 | skipMainClassScanning = false // set to true might increase build-speed 132 | 133 | skipNativeLauncherWorkaround124 = false 134 | skipNativeLauncherWorkaround167 = false 135 | skipNativeLauncherWorkaround205 = false 136 | skipJNLPRessourcePathWorkaround182 = false 137 | skipSigningJarFilesJNLP185 = false 138 | skipSizeRecalculationForJNLP185 = false 139 | skipMacBundlerWorkaround = false 140 | 141 | // gradle jfxRun 142 | runJavaParameter = null // String 143 | runAppParameter = null // String 144 | 145 | // per default the outcome of the gradle "jarTask" will be used, set this to specify otherwise (like proguard-output) 146 | alternativePathToJarFile = null // String 147 | 148 | // to disable patching of ant-javafx.jar, set this to false 149 | usePatchedJFXAntLib = true 150 | 151 | // making it able to support absolute paths, defaults to "false" for maintaining old behaviour 152 | checkForAbsolutePaths = false 153 | 154 | // gradle jfxGenerateKeyStore 155 | keyStore = "src/main/deploy/keystore.jks" 156 | keyStoreAlias = "myalias" 157 | keyStorePassword = "password" 158 | keyPassword = null // will default to keyStorePassword 159 | keyStoreType = "jks" 160 | overwriteKeyStore = false 161 | 162 | certDomain = null // required 163 | certOrgUnit = null // defaults to "none" 164 | certOrg = null // required 165 | certState = null // required 166 | certCountry = null // required 167 | } 168 | ``` 169 | 170 | 171 | Minimal setup of `build.gradle` 172 | ====================== 173 | ```groovy 174 | buildscript { 175 | dependencies { 176 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2' 177 | } 178 | repositories { 179 | mavenLocal() 180 | mavenCentral() 181 | 182 | } 183 | } 184 | apply plugin: 'java' 185 | 186 | repositories { 187 | mavenLocal() 188 | mavenCentral() 189 | } 190 | 191 | apply plugin: 'javafx-gradle-plugin' 192 | 193 | 194 | jfx { 195 | // minimal requirement for jfxJar-task 196 | mainClass = 'full.qualified.nameOf.TheMainClass' 197 | 198 | // minimal requirement for jfxNative-task 199 | vendor = 'YourName' 200 | } 201 | ``` 202 | 203 | Customize Icons 204 | =============== 205 | 206 | To customize the icons used in a native bundle, you have to provide the icons for the appropriate bundle. 207 | The icons must follow the file name convention in order to get picked up. 208 | 209 | > Tip: Set the `verbose` setting to true, to log which files are picked up from your deploy directory. 210 | 211 | ## macOS 212 | Icon location: `src/main/deploy/package/macosx` 213 | 214 | In macOS you can provide up to three different icons. 215 | * .app icon 216 | * volume icon 217 | * the background of the window, when opening the dmg volume 218 | 219 | The icon file name is depended on your `appName` setting of this plugin. 220 | 221 | | Type | Filename | 222 | | :---------------- |:------------------------- | 223 | | .app icon | \.icns | 224 | | volume icon | \-volume.icns | 225 | | volume background | \-background.png | 226 | 227 | The icon sizes should follow the specified sizes. 228 | http://iconhandbook.co.uk/reference/chart/osx/ 229 | 230 | ## Linux 231 | Icon location: `src/main/deploy/package/linux` 232 | 233 | For Linux you can provide one icon. 234 | 235 | The icon file name is depended on your `appName` setting of this plugin. 236 | 237 | | Type | Filename | 238 | | :---------------- |:--------------- | 239 | | application icon | \.png | 240 | 241 | >Whitespaces in the `appName` will be removed in order to lookup for the icon. 242 | For example a name like 'foo Bar' will lookup for a icon like 'fooBar.png' 243 | 244 | ## Windows 245 | Icon location: `src/main/deploy/package/windows` 246 | 247 | For Windows you can provide two different icons. 248 | * application icon 249 | * setup icon - the icon of the installer 250 | 251 | | Type | Filename | 252 | | :---------------- |:------------------------- | 253 | | .exe icon | \.ico | 254 | | setup exe icon | \-setup-icon.bmp | 255 | 256 | 257 | Gradle Tasks 258 | ============ 259 | 260 | * `gradle jfxJar` - Create executable JavaFX-jar 261 | * `gradle jfxNative` - Create native JavaFX-bundle (will run `jfxJar` first) 262 | * `gradle jfxRun` - Create the JavaFX-jar and runs it like you would do using `java -jar my-project-jfx.jar`, adjustable using `runJavaParameter`/`runAppParameter`-parameter 263 | * `gradle jfxGenerateKeyStore` - Create a Java keystore 264 | * `gradle jfxListBundlers` - List all possible bundlers available on this system, use '--info' parameter for detailed information 265 | 266 | 267 | Using `SNAPSHOT`-versions 268 | ========================= 269 | When you report a bug and this got worked around, you might be able to have access to some -SNAPSHOT-version, please adjust your buildscript: 270 | 271 | ```groovy 272 | buildscript { 273 | dependencies { 274 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.3-SNAPSHOT' 275 | } 276 | repositories { 277 | mavenLocal() 278 | mavenCentral() 279 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 280 | 281 | } 282 | } 283 | ``` 284 | 285 | 286 | Examples 287 | ======== 288 | 289 | Please look at the [examples-folder](/examples) to see some projects in action. 290 | 291 | 292 | Last Release Notes 293 | ================== 294 | 295 | **Version 8.8.2 (09-February-2017)** 296 | 297 | Bugfixes: 298 | * fixed `launcherArguments` of secondary launchers not being set correctly (fixes issue #55) 299 | 300 | 301 | (Not yet) Release(d) Notes 302 | ========================== 303 | 304 | upcoming Version 8.8.3 (???-2017) 305 | 306 | *nothing changed yet* 307 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | ## thanks to https://dzone.com/articles/continuous-integration-windows 2 | ## with some adjustments and exported yaml-settings 3 | 4 | version: '{build}' 5 | os: Windows Server 2012 6 | pull_requests: 7 | do_not_increment_build_number: true 8 | branches: 9 | only: 10 | - master 11 | skip_tags: true 12 | 13 | build_script: 14 | - gradlew.bat clean assemble install --info --no-daemon --stacktrace 15 | 16 | test_script: 17 | - gradlew.bat check --info --no-daemon --stacktrace 18 | 19 | cache: 20 | - C:\Users\appveyor\.gradle 21 | 22 | environment: 23 | matrix: 24 | - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 25 | - JAVA_HOME: C:\Program Files (x86)\Java\jdk1.8.0 26 | 27 | matrix: 28 | fast_finish: true 29 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import org.gradle.plugins.signing.Sign 18 | 19 | apply plugin: 'java' 20 | apply plugin: 'maven' 21 | apply plugin: 'signing' 22 | apply plugin: 'checkstyle' 23 | 24 | repositories { 25 | mavenLocal() 26 | mavenCentral() 27 | } 28 | 29 | dependencies { 30 | compile gradleApi() 31 | testCompile gradleTestKit() 32 | testCompile group: 'org.testng', name: 'testng', version: '6.10' 33 | // java 8 34 | if( file("${System.properties['java.home']}/../lib/ant-javafx.jar").exists() ){ 35 | compile files("${System.properties['java.home']}/../lib/ant-javafx.jar") 36 | } 37 | // java 9 38 | if( file("${System.properties['java.home']}/lib/ant-javafx.jar").exists() ){ 39 | compile files("${System.properties['java.home']}/lib/ant-javafx.jar") 40 | } 41 | compile 'org.ow2.asm:asm-all:5.1' 42 | runtime 'org.ow2.asm:asm-all:5.1' 43 | } 44 | 45 | group = 'de.dynamicfiles.projects.gradle.plugins' 46 | archivesBaseName = 'javafx-gradle-plugin' 47 | version = gradle.javafxGradlePluginVersion 48 | 49 | ext.isReleaseVersion = !version.endsWith("SNAPSHOT") 50 | 51 | task javadocJar(type: Jar) { 52 | classifier = 'javadoc' 53 | from javadoc 54 | } 55 | 56 | task sourcesJar(type: Jar) { 57 | classifier = 'sources' 58 | from sourceSets.main.allSource 59 | } 60 | 61 | // http://stackoverflow.com/a/22991189/1961102 62 | compileJava.dependsOn 'checkstyle' 63 | task checkstyle(type: Checkstyle) { 64 | configFile file("${project.rootDir}/config/checkstyle/checkstyle.xml") 65 | configProperties.checkstyleConfigDir = file("${project.rootDir}/config/checkstyle") 66 | source 'src' 67 | include '**/*.java' 68 | classpath = files() 69 | } 70 | test { 71 | useTestNG() 72 | testLogging.showStandardStreams = true 73 | } 74 | 75 | artifacts { 76 | archives jar 77 | archives javadocJar 78 | archives sourcesJar 79 | } 80 | signing { 81 | required { isReleaseVersion } 82 | sign configurations.archives 83 | } 84 | 85 | // read some information when required 86 | // https://docs.gradle.org/current/userguide/signing_plugin.html 87 | gradle.taskGraph.whenReady { taskGraph -> 88 | if (taskGraph.allTasks.any { it instanceof Sign } && isReleaseVersion ) { 89 | // Use Java 6's console to read from the console (no good for 90 | // a CI environment) 91 | Console console = System.console() 92 | console.printf "\n\nWe have to sign some things in this build." + 93 | "\n\nPlease enter your signing details.\n\n" 94 | 95 | def password = console.readPassword("PGP Private Key Password: ") 96 | 97 | allprojects { ext."signing.password" = password } 98 | 99 | console.printf "\nThanks.\n\n" 100 | } 101 | } 102 | // http://stackoverflow.com/a/27741137/1961102 103 | if(!hasProperty('ossrhUsername')) { 104 | ext.ossrhUsername = '' 105 | } 106 | if(!hasProperty('ossrhPassword')) { 107 | ext.ossrhPassword = '' 108 | } 109 | uploadArchives { 110 | repositories { 111 | mavenDeployer { 112 | if(isReleaseVersion) { 113 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 114 | } 115 | repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { 116 | authentication(userName: ossrhUsername, password: ossrhPassword) 117 | } 118 | 119 | snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { 120 | authentication(userName: ossrhUsername, password: ossrhPassword) 121 | } 122 | 123 | pom.project { 124 | name 'javafx-gradle-plugin' 125 | packaging 'jar' 126 | 127 | description 'The JavaFX Gradle Plugin provides a way to to assemble distributable bundles for JavaFX applications from within Gradle. It provides a wrapper around the JavaFX packaging tools which are provided as part of the JavaFX installation.' 128 | url 'https://github.com/FibreFoX/javafx-gradle-plugin' 129 | 130 | scm { 131 | connection 'scm:git:git://github.com/FibreFoX/javafx-gradle-plugin.git' 132 | developerConnection 'scm:git:git@github.com:FibreFoX/javafx-gradle-plugin.git' 133 | url 'https://github.com/FibreFoX/javafx-gradle-plugin' 134 | } 135 | 136 | licenses { 137 | license { 138 | name 'The Apache License, Version 2.0' 139 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 140 | distribution 'repo' 141 | } 142 | } 143 | 144 | developers { 145 | developer { 146 | id 'FibreFoX' 147 | name 'Danny Althoff' 148 | email 'fibrefox@dynamicfiles.de' 149 | } 150 | } 151 | 152 | profiles { 153 | profile { 154 | id 'java9-dependencies' 155 | activation { 156 | file { 157 | exists '${java.home}/lib/ant-javafx.jar' 158 | } 159 | } 160 | dependencies { 161 | dependency { 162 | groupId 'javafx-packager' 163 | artifactId 'javafx-packager' 164 | version '9' 165 | scope 'system' 166 | systemPath '${java.home}/lib/ant-javafx.jar' 167 | } 168 | } 169 | } 170 | profile { 171 | id 'java8-dependencies' 172 | activation { 173 | file { 174 | exists '${java.home}/../lib/ant-javafx.jar' 175 | } 176 | } 177 | dependencies { 178 | dependency { 179 | groupId 'javafx-packager' 180 | artifactId 'javafx-packager' 181 | version '1.8' 182 | scope 'system' 183 | systemPath '${java.home}/../lib/ant-javafx.jar' 184 | } 185 | } 186 | } 187 | } 188 | } 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /config/checkstyle/license.header: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ -------------------------------------------------------------------------------- /examples/additional-application-files/README.md: -------------------------------------------------------------------------------- 1 | Setup for generating some installer with additional application files 2 | ===================================================================== 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | For every system you target, you need some working system of that targeted one, because the generated result 11 | is generated for each architecture and the operating system using the local installed tool-sets. The used 12 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 13 | provided by the OpenJDK/OracleJDK. 14 | 15 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 16 | `build/jfx/native/additional-application-files/` while the installers reside below the `build/jfx/native/`-folder. 17 | 18 | To have additional files bundled, create some folder and set additionalAppResources to it's coordinates. 19 | This feature might come comfortable for having some README-files or anything else aside of your application. 20 | 21 | Please read the official documentation of Oracle about the tools you are required to install for having 22 | installers be generated. 23 | -------------------------------------------------------------------------------- /examples/additional-application-files/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | } 11 | } 12 | apply plugin: 'java' 13 | 14 | repositories { 15 | mavenLocal() 16 | mavenCentral() 17 | } 18 | 19 | apply plugin: 'javafx-gradle-plugin' 20 | 21 | 22 | jfx { 23 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 24 | vendor = 'YourName' 25 | additionalAppResources = 'src/main/additional-files' 26 | // copyAdditionalAppResourcesToJar = true 27 | } 28 | -------------------------------------------------------------------------------- /examples/additional-application-files/src/main/additional-files/dummy.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/additional-application-files/src/main/additional-files/dummy.txt -------------------------------------------------------------------------------- /examples/additional-application-files/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/additional-bundler-files/README.md: -------------------------------------------------------------------------------- 1 | Setup for generating some installer with additional bundler files 2 | ================================================================= 3 | 4 | Creating special customized installer-building scripts is often requested, but providing these files 5 | is not always possible using `src/main/deploy/package`-folder nor using `additionalAppResources`, especially 6 | when these files should not be part of the application resources itself. 7 | 8 | All bundlers are using some temporary folder for letting the bundling toolsets work on it, including all 9 | application files, your overriding custom files for bundler scripts and the JRE (if existing, because its optional). 10 | The problem here is, that only file-overriding is possible by placing the named files into `src/main/deploy/`-folder, 11 | having additional files for example to encryption of specialized installer modules (license-checks, system-checks) 12 | seems impossible. This feature was added since 8.7.0 of the javafx-gradle-plugin as part of a e-mail request. 13 | 14 | Before the bundlers are executed, all files inside the folder provided via the `additionalBundlerResources`-property 15 | inside your `jfx`-configuration will be copied to the working-folder of the bundler. Each bundler might have its 16 | own subfolder: 17 | * exe-installers on windows: "win-exe.image" 18 | * msi-installers on windows: "win-msi.image" 19 | 20 | Please take a look into the source-code for your special bundler, as this might be target of changes 21 | 22 | 23 | ```groovy 24 | jfx { 25 | // ... 26 | additionalBundlerResources = 'src/main/deploy/bundlers' 27 | bundleArguments = [ 28 | runtime: null 29 | ] 30 | // ... 31 | } 32 | ``` 33 | 34 | For every system you target, you need some working system of that targeted one, because the generated result 35 | is generated for each architecture and the operating system using the local installed tool-sets. The used 36 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 37 | provided by the OpenJDK/OracleJDK. 38 | 39 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 40 | `build/jfx/native/additional-bundler-files/` while the installers reside below the `build/jfx/native/`-folder. 41 | 42 | Please read the official documentation of Oracle about the tools you are required to install for having 43 | installers be generated. 44 | -------------------------------------------------------------------------------- /examples/additional-bundler-files/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | additionalBundlerResources = 'src/main/deploy/bundlers' 27 | } 28 | -------------------------------------------------------------------------------- /examples/additional-bundler-files/src/main/deploy/bundlers/win-exe.image/license.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1031\deflangfe1031{\fonttbl{\f0\fnil\fcharset0 Calibri;}} 2 | {\*\generator Riched20 6.3.9600}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 3 | \pard\sa200\sl276\slmult1\f0\fs22\lang7 license text\par 4 | } 5 | -------------------------------------------------------------------------------- /examples/additional-bundler-files/src/main/deploy/package/windows/additional-bundler-files.iss: -------------------------------------------------------------------------------- 1 | ;This file will be executed next to the application bundle image 2 | ;I.e. current directory will contain folder additional-bundler-files with application files 3 | [Setup] 4 | AppId={{de.dynamicfiles.projects.gradle.example}} 5 | AppName=additional-bundler-files 6 | AppVersion=1.0 7 | AppVerName=additional-bundler-files 1.0 8 | AppPublisher=YourName 9 | AppComments=additional-bundler-files 10 | AppCopyright=Copyright (C) 2016 11 | ;AppPublisherURL=http://java.com/ 12 | ;AppSupportURL=http://java.com/ 13 | ;AppUpdatesURL=http://java.com/ 14 | DefaultDirName={localappdata}\additional-bundler-files 15 | DisableStartupPrompt=Yes 16 | DisableDirPage=Yes 17 | DisableProgramGroupPage=Yes 18 | DisableReadyPage=Yes 19 | DisableFinishedPage=Yes 20 | DisableWelcomePage=Yes 21 | DefaultGroupName=YourName 22 | ;Optional License 23 | 24 | ; modified version from the JavaFX-Gradle-Plugin project 25 | ; we modified the file by adding the filename without having 26 | ; this being part of the application resources 27 | LicenseFile=license.rtf 28 | 29 | 30 | ;WinXP or above 31 | MinVersion=0,5.1 32 | OutputBaseFilename=additional-bundler-files-1.0 33 | Compression=lzma 34 | SolidCompression=yes 35 | PrivilegesRequired=lowest 36 | SetupIconFile=additional-bundler-files\additional-bundler-files.ico 37 | UninstallDisplayIcon={app}\additional-bundler-files.ico 38 | UninstallDisplayName=additional-bundler-files 39 | WizardImageStretch=No 40 | WizardSmallImageFile=additional-bundler-files-setup-icon.bmp 41 | ArchitecturesInstallIn64BitMode=x64 42 | 43 | 44 | [Languages] 45 | Name: "english"; MessagesFile: "compiler:Default.isl" 46 | 47 | [Files] 48 | Source: "additional-bundler-files\additional-bundler-files.exe"; DestDir: "{app}"; Flags: ignoreversion 49 | Source: "additional-bundler-files\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs 50 | 51 | [Icons] 52 | Name: "{group}\additional-bundler-files"; Filename: "{app}\additional-bundler-files.exe"; IconFilename: "{app}\additional-bundler-files.ico"; Check: returnTrue() 53 | Name: "{commondesktop}\additional-bundler-files"; Filename: "{app}\additional-bundler-files.exe"; IconFilename: "{app}\additional-bundler-files.ico"; Check: returnFalse() 54 | 55 | 56 | [Run] 57 | Filename: "{app}\additional-bundler-files.exe"; Parameters: "-Xappcds:generatecache"; Check: returnFalse() 58 | Filename: "{app}\additional-bundler-files.exe"; Description: "{cm:LaunchProgram,additional-bundler-files}"; Flags: nowait postinstall skipifsilent; Check: returnTrue() 59 | Filename: "{app}\additional-bundler-files.exe"; Parameters: "-install -svcName ""additional-bundler-files"" -svcDesc ""additional-bundler-files"" -mainExe ""additional-bundler-files.exe"" "; Check: returnFalse() 60 | 61 | [UninstallRun] 62 | Filename: "{app}\additional-bundler-files.exe "; Parameters: "-uninstall -svcName additional-bundler-files -stopOnUninstall"; Check: returnFalse() 63 | 64 | [Code] 65 | function returnTrue(): Boolean; 66 | begin 67 | Result := True; 68 | end; 69 | 70 | function returnFalse(): Boolean; 71 | begin 72 | Result := False; 73 | end; 74 | 75 | function InitializeSetup(): Boolean; 76 | begin 77 | // Possible future improvements: 78 | // if version less or same => just launch app 79 | // if upgrade => check if same app is running and wait for it to exit 80 | // Add pack200/unpack200 support? 81 | Result := True; 82 | end; 83 | -------------------------------------------------------------------------------- /examples/additional-bundler-files/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/adjusted-launcher-icon/README.md: -------------------------------------------------------------------------------- 1 | Setup for generating some executable native launcher with a cusomized launcher icon 2 | =================================================================================== 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | To change the launcher icon, put place a file named 'adjusted-launcher-icon.ico' (at least for windows) 11 | into the folder `src/main/deploy/package/windows` for the bundler being able to pick it up. This file will be used 12 | as icon for your native launcher including the installer (at least for windows exe-installer). 13 | 14 | For every system you target, you need some working system of that targeted one, because the generated result 15 | is generated for each architecture and the operating system using the local installed tool-sets. The used 16 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 17 | provided by the OpenJDK/OracleJDK. 18 | 19 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 20 | `build/jfx/native/adjusted-launcher-icon/` while the installers reside below the `build/jfx/native/`-folder. 21 | 22 | Please read the official documentation of Oracle about the tools you are required to install for having 23 | installers be generated. 24 | -------------------------------------------------------------------------------- /examples/adjusted-launcher-icon/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | } 27 | -------------------------------------------------------------------------------- /examples/adjusted-launcher-icon/src/main/deploy/package/windows/adjusted-launcher-icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/adjusted-launcher-icon/src/main/deploy/package/windows/adjusted-launcher-icon.ico -------------------------------------------------------------------------------- /examples/adjusted-launcher-icon/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/debian-installer-with-license/README.md: -------------------------------------------------------------------------------- 1 | Debain Installer with License 2 | ============================= 3 | 4 | Creating installers with licenses needs some special adjustments. On Debian-systems, the bundler requires 5 | the license to be in text-file format to include it into the installer routines. 6 | 7 | Just make sure to have that text-file being available inside the folder specified via 8 | `additionalAppResources`- property, and please make sure it is not inside any subfolder as the bundler 9 | does not look into them correctly. 10 | 11 | You need to specify some license-type aswell for having the `.deb`-builder and `.rpm`-builder working 12 | correct, please make sure to use some known string for the license-type. The Fedora-project has a list 13 | online to take from: https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses 14 | 15 | 16 | ```groovy 17 | jfx { 18 | // ... 19 | additionalAppResources = 'src/main/additionalFiles' 20 | bundleArguments = [ 21 | licenseType: 'ASL 2.0', 22 | licenseFile: 'LICENSE' 23 | ] 24 | // ... 25 | } 26 | ``` 27 | 28 | For every system you target, you need some working system of that targeted one, because the generated result 29 | is generated for each architecture and the operating system using the local installed tool-sets. The used 30 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 31 | provided by the OpenJDK/OracleJDK. 32 | 33 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 34 | `build/jfx/native/windows-installer-with-license/` while the installers reside below the `build/jfx/native/`-folder. 35 | 36 | Please read the official documentation of Oracle about the tools you are required to install for having 37 | installers be generated. 38 | -------------------------------------------------------------------------------- /examples/debian-installer-with-license/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | additionalAppResources = 'src/main/additionalFiles' 27 | bundleArguments = [ 28 | // please see https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses for short-names of the licenses 29 | licenseType: 'ASL 2.0', 30 | licenseFile: 'LICENSE' 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /examples/debian-installer-with-license/src/main/additionalFiles/LICENSE: -------------------------------------------------------------------------------- 1 | Your license text 2 | -------------------------------------------------------------------------------- /examples/debian-installer-with-license/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/file-associations/README.md: -------------------------------------------------------------------------------- 1 | Setup for generating some installer with file associations 2 | ========================================================== 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | For every system you target, you need some working system of that targeted one, because the generated result 11 | is generated for each architecture and the operating system using the local installed tool-sets. The used 12 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 13 | provided by the OpenJDK/OracleJDK. 14 | 15 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 16 | `build/jfx/native/file-associations/` while the installers reside below the `build/jfx/native/`-folder. 17 | 18 | When installing, there are some file association registered on your system (when supported). Double-clicking 19 | these files will start your application having that file as argument. To have this working, you need to specify 20 | at least some extensions and some mime-type (called contentType). For further adjustments you can set some 21 | file description and some special icon, which needs to be the same file-format supported on your target system. 22 | 23 | Please read the official documentation of Oracle about the tools you are required to install for having 24 | installers be generated. 25 | -------------------------------------------------------------------------------- /examples/file-associations/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | } 11 | } 12 | apply plugin: 'java' 13 | 14 | repositories { 15 | mavenLocal() 16 | mavenCentral() 17 | } 18 | 19 | apply plugin: 'javafx-gradle-plugin' 20 | 21 | 22 | jfx { 23 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 24 | vendor = 'YourName' 25 | fileAssociations = [ 26 | [ 27 | description: 'simple description of file abc', 28 | extensions: 'abc', 29 | contentType: 'application/x-example-abc' 30 | ], 31 | [ 32 | description: 'simple description of file efg', 33 | extensions: 'efg', 34 | contentType: 'application/x-example-efg', 35 | icon: 'src/main/deploy/file-associations.ico' 36 | ] 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /examples/file-associations/src/main/deploy/file-associations.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/file-associations/src/main/deploy/file-associations.ico -------------------------------------------------------------------------------- /examples/file-associations/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/README.md: -------------------------------------------------------------------------------- 1 | Setup for using ProGuard with the javafx-gradle-plugin 2 | ====================================================== 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | For having ProGuard to work on your jar-file, you have to make sure that the gradle-task ProGuardTask 11 | will run before the `jfxJar`-task provided with the javafx-gradle-plugin is executed. This projects shows 12 | the needed manual stitching to have all tasks being in the right order including some cleanup. 13 | 14 | You can call `gradle jfxJar` and `gradle jfxNative` which will all produce some ProGuard obfruscated outcome. 15 | 16 | For every system you target, you need some working system of that targeted one, because the generated result 17 | is generated for each architecture and the operating system using the local installed tool-sets. The used 18 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 19 | provided by the OpenJDK/OracleJDK. 20 | 21 | You can find the JavaFX-JAR-file at `build/jfx/app/javafx-proguard-gradle-jfx.jar` and your native launcher can be 22 | found at `build/jfx/native/javafx-proguard-gradle/` while the installers reside below the`build/jfx/native/`-folder. 23 | 24 | Please read the official documentation of Oracle about the tools you are required to install for having 25 | installers be generated. 26 | 27 | Please read the official documentation of ProGuard about the setup of the contents inside the `proguard.conf`-file, 28 | this is not part of the scope of this example-project. 29 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/build.gradle: -------------------------------------------------------------------------------- 1 | // this example rebuilds the integration test project "08-build-with-proguard" from the javafx-maven-plugin 2 | 3 | 4 | buildscript { 5 | apply from: '../../version.gradle' 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | } 11 | dependencies { 12 | // provides javafx-gradle-plugin 13 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 14 | // provides proguard.gradle.ProGuardTask (including all requirements) 15 | classpath 'net.sf.proguard:proguard-gradle:5.2.1' 16 | } 17 | } 18 | 19 | apply plugin: 'java' 20 | 21 | repositories { 22 | mavenLocal() 23 | mavenCentral() 24 | } 25 | 26 | dependencies{ 27 | compile 'com.miglayout:miglayout-javafx:4.2' 28 | compile 'commons-lang:commons-lang:2.6' 29 | compile 'org.slf4j:slf4j-api:1.6.1' 30 | compile 'org.slf4j:jcl-over-slf4j:1.6.1' 31 | compile 'org.slf4j:slf4j-log4j12:1.6.1' 32 | compile 'log4j:log4j:1.2.16' 33 | } 34 | 35 | apply plugin: 'javafx-gradle-plugin' 36 | 37 | jfx { 38 | verbose = true 39 | mainClass = 'com.zenjava.test.javafx_and_proguard.MainApp' 40 | appName = 'javafx-proguard-gradle' 41 | manifestAttributes = [ 42 | someElement: "hello world" 43 | ] 44 | jfxMainAppJarName = 'javafx-proguard-gradle-jfx.jar' 45 | vendor = "your fancy company" 46 | bundleArguments = [ 47 | runtime: null 48 | ] 49 | alternativePathToJarFile 'build/libs/javafx-proguard-gradle.out.jar' 50 | } 51 | 52 | // for more details, see: http://proguard.sourceforge.net/manual/gradle.html 53 | task myProguardTask(type: proguard.gradle.ProGuardTask) { 54 | configuration 'proguard.conf' 55 | 56 | // make all runtime-dependencies available while obfruscating 57 | configurations.runtime.resolve().each { 58 | libraryjars file(it.getAbsolutePath()) 59 | } 60 | 61 | injars 'build/libs/javafx-proguard-gradle.jar' 62 | outjars 'build/libs/javafx-proguard-gradle.out.jar' 63 | } 64 | 65 | // set task-dependencies 66 | jfxJar.dependsOn myProguardTask 67 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/proguard.conf: -------------------------------------------------------------------------------- 1 | -dontoptimize 2 | 3 | -libraryjars /lib/rt.jar 4 | -libraryjars /lib/ext/jfxrt.jar 5 | -libraryjars /lib/jce.jar 6 | 7 | # Save meta-data for stack traces 8 | -renamesourcefileattribute SourceFile 9 | -keepattributes SourceFile,LineNumberTable 10 | 11 | # Rename FXML files together with related views 12 | -adaptresourcefilenames **.fxml,**.png,**.css 13 | -adaptresourcefilecontents **.fxml 14 | -adaptclassstrings 15 | 16 | # Keep all annotations and meta-data 17 | -keepattributes *Annotation*,Signature,EnclosingMethod 18 | 19 | # Keep entry-point class 20 | -keep class com.zenjava.test.javafx_and_proguard.MainApp { 21 | public static void main(java.lang.String[]); 22 | } 23 | 24 | # Keep all classes inside application 25 | -keep,allowobfuscation class com.zenjava.test.javafx_and_proguard.** { 26 | } 27 | 28 | # Keep names of fields marked with @FXML attribute 29 | -keepclassmembers class * { 30 | @javafx.fxml.FXML *; 31 | } 32 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='javafx-proguard-gradle' 2 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/java/com/zenjava/test/javafx_and_proguard/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.zenjava.test.javafx_and_proguard; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.control.Label; 5 | import javafx.scene.control.TextField; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class HelloController { 11 | 12 | @FXML 13 | private Label lblClassName; 14 | 15 | @FXML 16 | private void initialize() { 17 | lblClassName.setText(this.getClass().getCanonicalName()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/java/com/zenjava/test/javafx_and_proguard/MainApp.java: -------------------------------------------------------------------------------- 1 | package com.zenjava.test.javafx_and_proguard; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Parent; 6 | import javafx.scene.Scene; 7 | import javafx.stage.Stage; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class MainApp extends Application { 12 | 13 | private static final Logger log = LoggerFactory.getLogger(MainApp.class); 14 | 15 | public static void main(String[] args) throws Exception { 16 | launch(args); 17 | } 18 | 19 | @Override 20 | public void start(Stage stage) throws Exception { 21 | 22 | log.info("Starting Hello JavaFX and Maven demonstration application"); 23 | 24 | String fxmlFile = "/com/zenjava/test/javafx_and_proguard/" + HelloController.class.getSimpleName() + ".fxml"; 25 | log.debug("Loading FXML for main view from: {}", fxmlFile); 26 | FXMLLoader loader = new FXMLLoader(); 27 | Parent rootNode = (Parent) loader.load(getClass().getResourceAsStream(fxmlFile)); 28 | 29 | log.debug("Showing JFX scene"); 30 | Scene scene = new Scene(rootNode, 400, 200); 31 | scene.getStylesheets().add("/styles/styles.css"); 32 | 33 | stage.setTitle("Hello JavaFX and Maven"); 34 | stage.setScene(scene); 35 | stage.show(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/resources/com/zenjava/test/javafx_and_proguard/HelloController.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/resources/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/javafx-proguard-gradle/src/main/resources/images/background.jpg -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/javafx-proguard-gradle/src/main/resources/styles/styles.css: -------------------------------------------------------------------------------- 1 | /* Application wide styles */ 2 | 3 | .label { 4 | -fx-font-size: 12px; 5 | -fx-font-weight: bold; 6 | -fx-text-fill: #333333; 7 | -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); 8 | } 9 | 10 | .button { 11 | -fx-text-fill: white; 12 | -fx-font-family: "Arial Narrow"; 13 | -fx-font-weight: bold; 14 | -fx-background-color: linear-gradient(#61a2b1, #2A5058); 15 | -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 ); 16 | } 17 | 18 | .button:hover{ 19 | -fx-base: #395bae; 20 | } 21 | 22 | /* Component specific styles */ 23 | 24 | 25 | .main-panel { 26 | -fx-background-image: url("../images/background.jpg"); 27 | } 28 | 29 | .hello-message { 30 | -fx-text-fill: #AA0000; 31 | -fx-font-weight: bold; 32 | -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); 33 | } 34 | -------------------------------------------------------------------------------- /examples/jnlp-minimal/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | bundler = 'jnlp' 27 | bundleArguments = [ 28 | 'jnlp.outfile': 'myAwesomeApp' 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /examples/jnlp-minimal/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/minimal-setup-jfxjar/README.md: -------------------------------------------------------------------------------- 1 | Minimal setup for generating some executable JavaFX-JAR 2 | ======================================================= 3 | 4 | Calling `gradle jfxJar` will generate some executable jar-file with javafx-support. 5 | 6 | You can find that jar-file at `build/jfx/app/project-jfx.jar`. -------------------------------------------------------------------------------- /examples/minimal-setup-jfxjar/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | } 26 | -------------------------------------------------------------------------------- /examples/minimal-setup-jfxjar/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/minimal-setup-jfxnative/README.md: -------------------------------------------------------------------------------- 1 | Minimal setup for generating some executable native launcher 2 | ============================================================ 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | For every system you target, you need some working system of that targeted one, because the generated result 11 | is generated for each architecture and the operating system using the local installed tool-sets. The used 12 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 13 | provided by the OpenJDK/OracleJDK. 14 | 15 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 16 | `build/jfx/native/minimal-setup-jfxnative/` while the installers reside below the `build/jfx/native/`-folder. 17 | 18 | Please read the official documentation of Oracle about the tools you are required to install for having 19 | installers be generated. 20 | -------------------------------------------------------------------------------- /examples/minimal-setup-jfxnative/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | } 27 | -------------------------------------------------------------------------------- /examples/minimal-setup-jfxnative/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/minimal-setup-without-bundled-jre/README.md: -------------------------------------------------------------------------------- 1 | Minimal setup for generating some executable native launcher without bundled JRE 2 | ================================================================================ 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | To exclude the normally included/bundled Java Runtime Environment, just set the `runtime` inside 11 | the `bundleArguments` to `null`. This will create smaller installers, but requires your application 12 | to solely rely on the assumption that you end-user has installed the right version of some JRE. 13 | 14 | ```groovy 15 | jfx { 16 | // ... 17 | bundleArguments = [ 18 | runtime: null 19 | ] 20 | // ... 21 | } 22 | ``` 23 | 24 | For every system you target, you need some working system of that targeted one, because the generated result 25 | is generated for each architecture and the operating system using the local installed tool-sets. The used 26 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 27 | provided by the OpenJDK/OracleJDK. 28 | 29 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 30 | `build/jfx/native/minimal-setup-without-bundled-jre/` while the installers reside below the `build/jfx/native/`-folder. 31 | 32 | Please read the official documentation of Oracle about the tools you are required to install for having 33 | installers be generated. 34 | -------------------------------------------------------------------------------- /examples/minimal-setup-without-bundled-jre/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | bundleArguments = [ 27 | runtime: null 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /examples/minimal-setup-without-bundled-jre/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/multi-module-project/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/multi-module-project/.gitkeep -------------------------------------------------------------------------------- /examples/secondary-native-launchers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/examples/secondary-native-launchers/.gitkeep -------------------------------------------------------------------------------- /examples/simpler-application-name/README.md: -------------------------------------------------------------------------------- 1 | Setup for generating some executable native launcher with a simple name 2 | ======================================================================= 3 | 4 | Calling `gradle jfxNative` will generate some executable jar-file with javafx-support and will 5 | generate some executable file able to run on your machine/achitecture, which is called native launcher. 6 | Depending on the tools you have installed, there will be some installers generated too. 7 | 8 | You need to set some `vendor`-name which is required for generating installers. 9 | 10 | For every system you target, you need some working system of that targeted one, because the generated result 11 | is generated for each architecture and the operating system using the local installed tool-sets. The used 12 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 13 | provided by the OpenJDK/OracleJDK. 14 | 15 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 16 | `build/jfx/native/moreSimpleAppName/` while the installers reside below the `build/jfx/native/`-folder. 17 | 18 | Some notes about the appName: this setting changes the files being search for launcher icon, installer filenames 19 | and other application name-related stuff. To override the default icon, you have to place a file named 20 | 'moreSimpleAppName.ico' (at least for windows) into the folder `src/main/deploy/windows` for the bundler 21 | being able to pick it up. 22 | 23 | Please read the official documentation of Oracle about the tools you are required to install for having 24 | installers be generated. 25 | -------------------------------------------------------------------------------- /examples/simpler-application-name/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | appName = 'moreSimpleAppName' 27 | } 28 | -------------------------------------------------------------------------------- /examples/simpler-application-name/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/windows-installer-with-license/README.md: -------------------------------------------------------------------------------- 1 | Windows Installer with License 2 | ============================== 3 | 4 | Creating installers with license displayed needs some special adjustments. On Windows-systems, 5 | the bundler requires the license to be in RTF-file-format to include it into the installer routines. 6 | 7 | Just make sure to have that RTF-file being available inside the folder specified via 8 | `additionalAppResources`- property, and please make sure it is not inside any subfolder as the bundler 9 | does not look into them correctly. 10 | 11 | 12 | ```groovy 13 | jfx { 14 | // ... 15 | additionalAppResources = 'src/main/additionalFiles' 16 | bundleArguments = [ 17 | runtime: null, 18 | licenseFile: 'license.rtf' 19 | ] 20 | // ... 21 | } 22 | ``` 23 | 24 | For every system you target, you need some working system of that targeted one, because the generated result 25 | is generated for each architecture and the operating system using the local installed tool-sets. The used 26 | java(fx)packager is just a wrapper around these tools and the javafx-gradle-plugin is just a wrapper of that 27 | provided by the OpenJDK/OracleJDK. 28 | 29 | You can find the JavaFX-JAR-file at `build/jfx/app/project-jfx.jar` and you native launcher can be found at 30 | `build/jfx/native/windows-installer-with-license/` while the installers reside below the `build/jfx/native/`-folder. 31 | 32 | Please read the official documentation of Oracle about the tools you are required to install for having 33 | installers be generated. 34 | -------------------------------------------------------------------------------- /examples/windows-installer-with-license/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: '../../version.gradle' 3 | dependencies { 4 | classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: "${gradle.javafxGradlePluginVersion}" 5 | } 6 | repositories { 7 | mavenLocal() 8 | mavenCentral() 9 | maven { url "https://oss.sonatype.org/content/repositories/snapshots" } 10 | 11 | } 12 | } 13 | apply plugin: 'java' 14 | 15 | repositories { 16 | mavenLocal() 17 | mavenCentral() 18 | } 19 | 20 | apply plugin: 'javafx-gradle-plugin' 21 | 22 | 23 | jfx { 24 | mainClass = 'de.dynamicfiles.projects.gradle.example.MainClass' 25 | vendor = 'YourName' 26 | additionalAppResources = 'src/main/additionalFiles' 27 | bundleArguments = [ 28 | runtime: null, 29 | licenseFile: 'license.rtf' 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /examples/windows-installer-with-license/src/main/additionalFiles/license.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1031\deflangfe1031{\fonttbl{\f0\fnil\fcharset0 Calibri;}} 2 | {\*\generator Riched20 6.3.9600}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 3 | \pard\sa200\sl276\slmult1\f0\fs22\lang7 license text\par 4 | } 5 | -------------------------------------------------------------------------------- /examples/windows-installer-with-license/src/main/java/de/dynamicfiles/projects/gradle/example/MainClass.java: -------------------------------------------------------------------------------- 1 | package de.dynamicfiles.projects.gradle.example; 2 | 3 | import javafx.stage.Stage; 4 | 5 | /** 6 | * 7 | * @author Danny Althoff 8 | */ 9 | public class MainClass extends javafx.application.Application { 10 | 11 | public static void main(String[] args) { 12 | MainClass.launch(args); 13 | } 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | // here you can do your normal JavaFX magic ;) 18 | System.exit(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FibreFoX/javafx-gradle-plugin/178c9f6dc6a170a80f4b00bdc229a0043c42d098/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStorePath=wrapper/dists 5 | zipStoreBase=GRADLE_USER_HOME 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'javafx-gradle-plugin' 2 | 3 | apply from: 'version.gradle' -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/JavaFXGradlePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxGenerateKeystoreTask; 19 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask; 20 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxJarTask; 21 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxListBundlersTask; 22 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxRunTask; 23 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal.JavaDetectionTools; 24 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal.MonkeyPatcher; 25 | import java.io.File; 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | import java.net.URLClassLoader; 29 | import java.util.ArrayList; 30 | import java.util.Arrays; 31 | import java.util.List; 32 | import java.util.stream.Collectors; 33 | import org.gradle.api.GradleException; 34 | import org.gradle.api.Plugin; 35 | import org.gradle.api.Project; 36 | 37 | /** 38 | * 39 | * @author Danny Althoff 40 | */ 41 | public class JavaFXGradlePlugin implements Plugin { 42 | 43 | public static final String ANT_JAVAFX_JAR_FILENAME = "ant-javafx.jar"; 44 | 45 | @Override 46 | public void apply(Project project) { 47 | // can create jfx-jar only after jar-file was created 48 | if( project.getTasks().findByName("jar") == null ){ 49 | throw new GradleException("Could not find jar-task. Please make sure you are applying the 'java'-plugin."); 50 | } 51 | // gradle is lame, so replace existing tasks with MY NAMES ! *battle-cry* 52 | 53 | // tasks will be available for the buldscript prior full evaluation 54 | JfxJarTask jarTask = project.getTasks().replace(JfxJarTask.JFX_TASK_NAME, JfxJarTask.class); 55 | JfxNativeTask nativeTask = project.getTasks().replace(JfxNativeTask.JFX_TASK_NAME, JfxNativeTask.class); 56 | JfxGenerateKeystoreTask generateKeystoreTask = project.getTasks().replace(JfxGenerateKeystoreTask.JFX_TASK_NAME, JfxGenerateKeystoreTask.class); 57 | JfxRunTask runTask = project.getTasks().replace(JfxRunTask.JFX_TASK_NAME, JfxRunTask.class); 58 | JfxListBundlersTask jfxListBundlersTask = project.getTasks().replace(JfxListBundlersTask.JFX_TASK_NAME, JfxListBundlersTask.class); 59 | 60 | String taskGroupName = "JavaFX"; 61 | 62 | // this is for description 63 | jarTask.setGroup(taskGroupName); 64 | jarTask.setDescription("Create executable JavaFX-jar"); 65 | 66 | nativeTask.setGroup(taskGroupName); 67 | nativeTask.setDescription("Create native JavaFX-bundle"); 68 | 69 | generateKeystoreTask.setGroup(taskGroupName); 70 | generateKeystoreTask.setDescription("Create a Java keystore"); 71 | 72 | runTask.setGroup(taskGroupName); 73 | runTask.setDescription("Start generated JavaFX-jar"); 74 | 75 | jfxListBundlersTask.setGroup(taskGroupName); 76 | jfxListBundlersTask.setDescription("List all possible bundlers available on this system, use '--info' parameter for detailed information"); 77 | 78 | jarTask.dependsOn(project.getTasks().getByName("jar")); 79 | 80 | // always create jfx-jar before creating native launcher/bundle 81 | // (in maven I had to implement a lifecycle for this ... mehhh) 82 | nativeTask.dependsOn(jarTask); 83 | 84 | // to run our jfx-jar, we have to create it first ;) 85 | runTask.dependsOn(jarTask); 86 | 87 | // extend project-model to get our settings/configuration via nice configuration 88 | project.getExtensions().create("jfx", JavaFXGradlePluginExtension.class); 89 | 90 | // adding ant-javafx.jar AFTER evaluation, because otherwise we can't know if the user has choosen to NOT patch ant-javafx.jar (in case it is required) 91 | project.afterEvaluate(evaluatedProject -> { 92 | // ugly hack by adding ant-javafx-jar for only require to apply javafx-gradle-plugin 93 | // ... can't change via expected way: dependencies.add("classpath", jfxAntJar) 94 | // https://discuss.gradle.org/t/how-to-bootstrapp-buildscript-classpath-cannot-change-configuration-classpath-after-it-has-been-resolved/7442 95 | addJavaFXAntJARToGradleBuildpath(evaluatedProject); 96 | }); 97 | } 98 | 99 | private void addJavaFXAntJARToGradleBuildpath(Project project) { 100 | String jfxAntJarPath = "/../lib/" + ANT_JAVAFX_JAR_FILENAME; 101 | 102 | // on java 9, we have a different path 103 | if( JavaDetectionTools.IS_JAVA_9 ){ 104 | jfxAntJarPath = "/lib/" + ANT_JAVAFX_JAR_FILENAME; 105 | } 106 | 107 | // always use ant-javafx.jar from the executing JDK (do not use environment-specific paths) 108 | // per spec "java.home" points to the JRE: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html 109 | File jfxAntJar = new File(System.getProperty("java.home") + jfxAntJarPath); 110 | 111 | if( !jfxAntJar.exists() ){ 112 | throw new GradleException("Couldn't find Ant-JavaFX-library, please make sure you've installed some JDK which includes JavaFX (e.g. OracleJDK or OpenJDK and OpenJFX), and JAVA_HOME is set properly."); 113 | } 114 | 115 | // don't use SystemClassloader or current Thread-ClassLoader, as we are not maven here ;) 116 | ClassLoader buildscriptClassloader = project.getBuildscript().getClassLoader(); 117 | 118 | URLClassLoader sysloader; 119 | // when running inside IDE or while executing java-tests, this should be handled ;) 120 | if( "org.gradle.internal.classloader.CachingClassLoader".equals(buildscriptClassloader.getClass().getName()) ){ 121 | // project.getBuildscript().getDependencies().add("classpath", project.files(jfxAntJar)); 122 | // would result into: org.gradle.api.InvalidUserDataException: Cannot change dependencies of configuration ':classpath' after it has been resolved. 123 | 124 | // lets mess with the classloaders... 125 | project.getLogger().debug("Using JavaFXGradlePlugin-class classloader"); 126 | sysloader = (URLClassLoader) this.getClass().getClassLoader(); 127 | } else { 128 | project.getLogger().debug("Using buildscript classloader"); 129 | sysloader = (URLClassLoader) buildscriptClassloader; 130 | } 131 | 132 | // add ant-javafx.jar to the classloader (using a different way as javafx-maven-plugin ;D) 133 | try{ 134 | // I'm very sorry for this ugly condition :( 135 | boolean usePatchedJar = System.getProperty("os.name").toLowerCase().startsWith("windows") && isGradleDaemonMode() && (JavaDetectionTools.IS_JAVA_9 || (JavaDetectionTools.IS_JAVA_8 && JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(60))); 136 | boolean usePatchedJFXAntLib = project.getExtensions().getByType(JavaFXGradlePluginExtension.class).isUsePatchedJFXAntLib(); 137 | 138 | // check if patched jar is required 139 | if( usePatchedJar && !usePatchedJFXAntLib ){ 140 | usePatchedJar = false; 141 | project.getLogger().warn("You disabled the patching (by setting 'usePatchedJFXAntLib'-property to 'false' inside 'jfx'-configuration) of the " + ANT_JAVAFX_JAR_FILENAME + ", please make sure you know about the consequences."); 142 | } 143 | 144 | // check if already added! otherwise we would include/patch that file multiple times :( 145 | List loadedAntJavaFXLibs = Arrays.asList(sysloader.getURLs()).stream().filter(loadedURL -> { 146 | return loadedURL.toExternalForm().endsWith(ANT_JAVAFX_JAR_FILENAME); 147 | }).collect(Collectors.toList()); 148 | 149 | boolean alreadyLoaded = loadedAntJavaFXLibs.size() > 0; 150 | boolean workaroundLoaded = loadedAntJavaFXLibs.stream().filter(libURL -> libURL.toExternalForm().contains(MonkeyPatcher.WORKAROUND_DIRECTORY_NAME)).count() > 0; 151 | 152 | project.getLogger().debug("DEBUG > Having " + loadedAntJavaFXLibs.size() + " loadedJars"); 153 | 154 | // only when not loaded 155 | if( alreadyLoaded == false ){ 156 | List antJarList = new ArrayList<>(); 157 | if( usePatchedJar ){ 158 | URL patchedJfxAntJar = MonkeyPatcher.getPatchedJfxAntJar(); 159 | antJarList.add(patchedJfxAntJar); 160 | project.getLogger().info("using patched " + ANT_JAVAFX_JAR_FILENAME + ", located at > " + patchedJfxAntJar.toExternalForm()); 161 | } else { 162 | antJarList.add(jfxAntJar.toURI().toURL()); 163 | } 164 | // I really don't know, why there isn't a direct way to add some File... or just one URL, 165 | // but: no need to check if jar already was added ;) it's done inside 166 | org.gradle.internal.classloader.ClasspathUtil.addUrl(sysloader, antJarList); 167 | } else { 168 | if( !usePatchedJFXAntLib && workaroundLoaded ){ 169 | project.getLogger().warn("Please restart gradle-daemon! Patched " + ANT_JAVAFX_JAR_FILENAME + " is loaded, but you disabled to patch and use that file."); 170 | } 171 | } 172 | } catch(MalformedURLException ex){ 173 | throw new GradleException("Could not add Ant-JavaFX-JAR to plugin-classloader", ex); 174 | } 175 | } 176 | 177 | protected boolean isGradleDaemonMode() { 178 | String javaCommand = System.getProperty("sun.java.command"); 179 | return javaCommand != null && javaCommand.startsWith("org.gradle.launcher.daemon"); 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/dto/FileAssociation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.dto; 17 | 18 | import java.io.File; 19 | 20 | /** 21 | * 22 | * @author Danny Althoff 23 | */ 24 | public class FileAssociation { 25 | 26 | private String description = null; 27 | private String extensions = null; 28 | private String contentType = null; 29 | private File icon = null; 30 | 31 | public String getDescription() { 32 | return description; 33 | } 34 | 35 | public void setDescription(String description) { 36 | this.description = description; 37 | } 38 | 39 | public String getExtensions() { 40 | return extensions; 41 | } 42 | 43 | public void setExtensions(String extensions) { 44 | this.extensions = extensions; 45 | } 46 | 47 | public String getContentType() { 48 | return contentType; 49 | } 50 | 51 | public void setContentType(String contentType) { 52 | this.contentType = contentType; 53 | } 54 | 55 | public File getIcon() { 56 | return icon; 57 | } 58 | 59 | public void setIcon(File icon) { 60 | this.icon = icon; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/dto/NativeLauncher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.dto; 17 | 18 | import java.io.File; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * Data transfer object for configuring secondary native launchers. 24 | * 25 | * @author Danny Althoff 26 | */ 27 | public class NativeLauncher { 28 | 29 | /** 30 | * This has to be different than original appname, as all existing parameter are copied and this would be overwritten. 31 | */ 32 | private String appName = null; 33 | private String mainClass = null; 34 | private File jfxMainAppJarName = null; 35 | private Map jvmProperties = null; 36 | private List jvmArgs = null; 37 | private Map userJvmArgs = null; 38 | private String nativeReleaseVersion = null; 39 | private boolean needShortcut; 40 | private boolean needMenu; 41 | private String vendor = null; 42 | private String identifier = null; 43 | /** 44 | * To override default generated classpath, set this to your wanted value. 45 | */ 46 | private String classpath = null; 47 | private List launcherArguments = null; 48 | 49 | public String getAppName() { 50 | return appName; 51 | } 52 | 53 | public void setAppName(String appName) { 54 | this.appName = appName; 55 | } 56 | 57 | public String getMainClass() { 58 | return mainClass; 59 | } 60 | 61 | public void setMainClass(String mainClass) { 62 | this.mainClass = mainClass; 63 | } 64 | 65 | public File getJfxMainAppJarName() { 66 | return jfxMainAppJarName; 67 | } 68 | 69 | public void setJfxMainAppJarName(File jfxMainAppJarName) { 70 | this.jfxMainAppJarName = jfxMainAppJarName; 71 | } 72 | 73 | public Map getJvmProperties() { 74 | return jvmProperties; 75 | } 76 | 77 | public void setJvmProperties(Map jvmProperties) { 78 | this.jvmProperties = jvmProperties; 79 | } 80 | 81 | public List getJvmArgs() { 82 | return jvmArgs; 83 | } 84 | 85 | public void setJvmArgs(List jvmArgs) { 86 | this.jvmArgs = jvmArgs; 87 | } 88 | 89 | public Map getUserJvmArgs() { 90 | return userJvmArgs; 91 | } 92 | 93 | public void setUserJvmArgs(Map userJvmArgs) { 94 | this.userJvmArgs = userJvmArgs; 95 | } 96 | 97 | public String getNativeReleaseVersion() { 98 | return nativeReleaseVersion; 99 | } 100 | 101 | public void setNativeReleaseVersion(String nativeReleaseVersion) { 102 | this.nativeReleaseVersion = nativeReleaseVersion; 103 | } 104 | 105 | public boolean isNeedShortcut() { 106 | return needShortcut; 107 | } 108 | 109 | public void setNeedShortcut(boolean needShortcut) { 110 | this.needShortcut = needShortcut; 111 | } 112 | 113 | public boolean isNeedMenu() { 114 | return needMenu; 115 | } 116 | 117 | public void setNeedMenu(boolean needMenu) { 118 | this.needMenu = needMenu; 119 | } 120 | 121 | public String getVendor() { 122 | return vendor; 123 | } 124 | 125 | public void setVendor(String vendor) { 126 | this.vendor = vendor; 127 | } 128 | 129 | public String getIdentifier() { 130 | return identifier; 131 | } 132 | 133 | public void setIdentifier(String identifier) { 134 | this.identifier = identifier; 135 | } 136 | 137 | public String getClasspath() { 138 | return classpath; 139 | } 140 | 141 | public void setClasspath(String classpath) { 142 | this.classpath = classpath; 143 | } 144 | 145 | public List getLauncherArguments() { 146 | return launcherArguments; 147 | } 148 | 149 | public void setLauncherArguments(List launcherArguments) { 150 | this.launcherArguments = launcherArguments; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/JfxGenerateKeystoreTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxGenerateKeystoreWorker; 19 | import org.gradle.api.internal.AbstractTask; 20 | import org.gradle.api.tasks.TaskAction; 21 | 22 | /** 23 | * 24 | * @author Danny Althoff 25 | */ 26 | public class JfxGenerateKeystoreTask extends AbstractTask { 27 | 28 | public static final String JFX_TASK_NAME = "jfxGenerateKeyStore"; 29 | 30 | @TaskAction 31 | public void jfxgeneratekeystore() { 32 | new JfxGenerateKeystoreWorker().jfxgeneratekeystore(this.getProject()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/JfxJarTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxJarWorker; 19 | import org.gradle.api.internal.AbstractTask; 20 | import org.gradle.api.tasks.TaskAction; 21 | 22 | /** 23 | * 24 | * @author Danny Althoff 25 | */ 26 | public class JfxJarTask extends AbstractTask { 27 | 28 | public static final String JFX_TASK_NAME = "jfxJar"; 29 | 30 | @TaskAction 31 | public void jfxjar() { 32 | new JfxJarWorker().jfxjar(this.getProject()); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/JfxListBundlersTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxListBundlersWorker; 19 | import org.gradle.api.internal.AbstractTask; 20 | import org.gradle.api.tasks.TaskAction; 21 | 22 | /** 23 | * 24 | * @author Danny Althoff 25 | */ 26 | public class JfxListBundlersTask extends AbstractTask { 27 | 28 | public static final String JFX_TASK_NAME = "jfxListBundlers"; 29 | 30 | @TaskAction 31 | public void jfxlistbundlers() { 32 | new JfxListBundlersWorker().jfxlistbundlers(this.getProject()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/JfxNativeTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxNativeWorker; 19 | import org.gradle.api.internal.AbstractTask; 20 | import org.gradle.api.tasks.TaskAction; 21 | 22 | /** 23 | * 24 | * @author Danny Althoff 25 | */ 26 | public class JfxNativeTask extends AbstractTask { 27 | 28 | public static final String JFX_TASK_NAME = "jfxNative"; 29 | 30 | @TaskAction 31 | public void jfxnative() { 32 | new JfxNativeWorker().jfxnative(this.getProject()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/JfxRunTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxRunWorker; 19 | import org.gradle.api.internal.AbstractTask; 20 | import org.gradle.api.tasks.TaskAction; 21 | 22 | /** 23 | * 24 | * @author Danny Althoff 25 | */ 26 | public class JfxRunTask extends AbstractTask { 27 | 28 | public static final String JFX_TASK_NAME = "jfxRun"; 29 | 30 | @TaskAction 31 | public void jfxrun() { 32 | new JfxRunWorker().jfxrun(this.getProject()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/internal/JavaDetectionTools.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal; 17 | 18 | /** 19 | * @author Danny Althoff 20 | */ 21 | public class JavaDetectionTools { 22 | 23 | public static final boolean IS_JAVA_8 = isJavaVersion(8); 24 | public static final boolean IS_JAVA_9 = !IS_JAVA_8 && isJavaVersion(9) || isJavaVersion(9, true); 25 | 26 | public static boolean isJavaVersion(int oracleJavaVersion, boolean noVersionOne) { 27 | String javaVersion = System.getProperty("java.version"); 28 | if( noVersionOne ){ 29 | return javaVersion.startsWith(String.valueOf(oracleJavaVersion)); 30 | } 31 | return javaVersion.startsWith("1." + oracleJavaVersion); 32 | } 33 | 34 | public static boolean isJavaVersion(int oracleJavaVersion) { 35 | return isJavaVersion(oracleJavaVersion, false); 36 | } 37 | 38 | public static boolean isAtLeastOracleJavaUpdateVersion(int updateNumber) { 39 | String javaVersion = System.getProperty("java.version"); 40 | String[] javaVersionSplitted = javaVersion.split("_"); 41 | if( javaVersionSplitted.length <= 1 ){ 42 | return false; 43 | } 44 | String javaUpdateVersionRaw = javaVersionSplitted[1]; 45 | // required for any non-oracle JDK like the openjdk, as the reported version might result something like "1.8.0_45-internal" 46 | String javaUpdateVersion = javaUpdateVersionRaw.replaceAll("[^\\d]", ""); 47 | return Integer.parseInt(javaUpdateVersion, 10) >= updateNumber; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/internal/ParameterMapEntries.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal; 17 | 18 | import static com.oracle.tools.packager.AbstractBundler.IMAGES_ROOT; 19 | import com.oracle.tools.packager.BundlerParamInfo; 20 | import com.oracle.tools.packager.ConfigException; 21 | import com.oracle.tools.packager.StandardBundlerParam; 22 | import static com.oracle.tools.packager.StandardBundlerParam.VERSION; 23 | import java.io.File; 24 | import java.util.regex.Pattern; 25 | 26 | /** 27 | * 28 | * @author Danny Althoff 29 | */ 30 | public class ParameterMapEntries { 31 | 32 | // windows 33 | public static final BundlerParamInfo EXE_IMAGE_DIR = new StandardBundlerParam<>( 34 | "", // name, not required for us 35 | "", // description, not required for us 36 | "win.exe.imageDir", // string-key inside map 37 | File.class, // type 38 | params -> { // default value 39 | File imagesRoot = IMAGES_ROOT.fetchFrom(params); 40 | if( !imagesRoot.exists() ){ 41 | imagesRoot.mkdirs(); 42 | } 43 | return new File(imagesRoot, "win-exe.image"); 44 | }, 45 | (s, p) -> null); // string to non-string-conversion 46 | 47 | public static final BundlerParamInfo MSI_IMAGE_DIR = new StandardBundlerParam<>( 48 | "", // name, not required for us 49 | "", // description, not required for us 50 | "win.msi.imageDir", // string-key inside map 51 | File.class, // type 52 | params -> { // default value 53 | File imagesRoot = IMAGES_ROOT.fetchFrom(params); 54 | if( !imagesRoot.exists() ){ 55 | imagesRoot.mkdirs(); 56 | } 57 | return new File(imagesRoot, "win-msi.image"); 58 | }, 59 | (s, p) -> null); // string to non-string-conversion 60 | // linux 61 | 62 | private static final Pattern RPM_BUNDLE_NAME_PATTERN = Pattern.compile("[a-z\\d\\+\\-\\.\\_]+", Pattern.CASE_INSENSITIVE); 63 | 64 | public static final BundlerParamInfo RPM_BUNDLE_NAME = new StandardBundlerParam<>( 65 | "", // name, not required for us 66 | "", // description, not required for us 67 | "linux.bundleName", // string-key inside map 68 | String.class, // type 69 | params -> { // default value 70 | String nm = StandardBundlerParam.APP_NAME.fetchFrom(params); 71 | if( nm == null ){ 72 | return null; 73 | } 74 | 75 | // make sure to lower case and spaces become dashes 76 | nm = nm.toLowerCase().replaceAll("[ ]", "-"); 77 | 78 | return nm; 79 | }, 80 | (s, p) -> { // string to non-string-conversion 81 | if( !RPM_BUNDLE_NAME_PATTERN.matcher(s).matches() ){ 82 | throw new IllegalArgumentException( 83 | new ConfigException(new Exception("Bundle-Name was not compliant")) 84 | ); 85 | } 86 | 87 | return null; 88 | } 89 | ); 90 | 91 | public static final BundlerParamInfo RPM_IMAGE_DIR = new StandardBundlerParam<>( 92 | "", // name, not required for us 93 | "", // description, not required for us 94 | "linux.rpm.imageDir", // string-key inside map 95 | File.class, // type 96 | params -> { // default value 97 | File imagesRoot = IMAGES_ROOT.fetchFrom(params); 98 | if( !imagesRoot.exists() ){ 99 | imagesRoot.mkdirs(); 100 | } 101 | return new File(imagesRoot, "linux-rpm.image"); 102 | }, 103 | (s, p) -> new File(s)); // string to non-string-conversion 104 | 105 | public static final BundlerParamInfo DEB_FULL_PACKAGE_NAME = new StandardBundlerParam<>( 106 | "", // name, not required for us 107 | "", // description, not required for us 108 | "linux.deb.fullPackageName", // string-key inside map 109 | String.class, // type 110 | params -> RPM_BUNDLE_NAME.fetchFrom(params) + "-" + VERSION.fetchFrom(params), // default value 111 | (s, p) -> s); // string to non-string-conversion 112 | 113 | public static final BundlerParamInfo DEB_IMAGE_DIR = new StandardBundlerParam<>( 114 | "", // name, not required for us 115 | "", // description, not required for us 116 | "linux.deb.imageDir", // string-key inside map 117 | File.class, // type 118 | params -> { // default value 119 | File imagesRoot = IMAGES_ROOT.fetchFrom(params); 120 | if( !imagesRoot.exists() ){ 121 | imagesRoot.mkdirs(); 122 | } 123 | return new File(new File(imagesRoot, "linux-deb.image"), DEB_FULL_PACKAGE_NAME.fetchFrom(params)); 124 | }, 125 | (s, p) -> new File(s)); // string to non-string-conversion 126 | 127 | // mac 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/internal/Workarounds.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal; 17 | 18 | import com.oracle.tools.packager.Bundler; 19 | import com.oracle.tools.packager.IOUtils; 20 | import com.oracle.tools.packager.RelativeFileSet; 21 | import com.oracle.tools.packager.StandardBundlerParam; 22 | import de.dynamicfiles.projects.gradle.plugins.javafx.dto.NativeLauncher; 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.nio.file.Files; 26 | import java.nio.file.Path; 27 | import java.nio.file.StandardCopyOption; 28 | import java.nio.file.StandardOpenOption; 29 | import java.util.ArrayList; 30 | import java.util.HashMap; 31 | import java.util.HashSet; 32 | import java.util.List; 33 | import java.util.Map; 34 | import java.util.Optional; 35 | import java.util.Set; 36 | import java.util.regex.Matcher; 37 | import java.util.regex.Pattern; 38 | import java.util.stream.Stream; 39 | import org.gradle.api.logging.Logger; 40 | 41 | /** 42 | * 43 | * @author Danny Althoff 44 | */ 45 | public class Workarounds { 46 | 47 | private static final String JNLP_JAR_PATTERN = "(.*)href=(\".*?\")(.*)size=(\".*?\")(.*)"; 48 | 49 | private static final String CONFIG_FILE_EXTENSION = ".cfg"; 50 | 51 | private Logger logger; 52 | private File nativeOutputDir; 53 | 54 | public Workarounds(File nativeOutputDir, Logger logger) { 55 | this.logger = logger; 56 | this.nativeOutputDir = nativeOutputDir; 57 | } 58 | 59 | public Logger getLogger() { 60 | return logger; 61 | } 62 | 63 | public boolean isWorkaroundForBug124Needed() { 64 | return JavaDetectionTools.IS_JAVA_8 && JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(40) || JavaDetectionTools.IS_JAVA_9; 65 | } 66 | 67 | public boolean isWorkaroundForBug167Needed() { 68 | // this has been fixed and made available since 1.8.0u92: 69 | // http://www.oracle.com/technetwork/java/javase/2col/8u92-bugfixes-2949473.html 70 | return JavaDetectionTools.IS_JAVA_8 && JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(60) && !JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(92); 71 | } 72 | 73 | public boolean isWorkaroundForBug182Needed() { 74 | // jnlp-bundler uses RelativeFileSet, and generates system-dependent dividers (\ on windows, / on others) 75 | return File.separator.equals("\\"); 76 | } 77 | 78 | public boolean isWorkaroundForBug185Needed(Map params) { 79 | return params.containsKey("jnlp.allPermisions") && Boolean.parseBoolean(String.valueOf(params.get("jnlp.allPermisions"))); 80 | } 81 | 82 | public boolean isWorkaroundForBug205Needed() { 83 | return (JavaDetectionTools.IS_JAVA_8 && JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(40)) || JavaDetectionTools.IS_JAVA_9; 84 | } 85 | 86 | protected void applyNativeLauncherWorkaround(String appName) { 87 | // check appName containing any dots 88 | boolean needsWorkaround = appName.contains("."); 89 | if( !needsWorkaround ){ 90 | return; 91 | } 92 | // rename .cfg-file (makes it able to create running applications again, even within installer) 93 | String newConfigFileName = appName.substring(0, appName.lastIndexOf(".")); 94 | Path appPath = nativeOutputDir.toPath().resolve(appName).resolve("app"); 95 | Path oldConfigFile = appPath.resolve(appName + CONFIG_FILE_EXTENSION); 96 | try{ 97 | Files.move(oldConfigFile, appPath.resolve(newConfigFileName + CONFIG_FILE_EXTENSION), StandardCopyOption.ATOMIC_MOVE); 98 | } catch(IOException ex){ 99 | getLogger().warn("Couldn't rename configfile. Please see issue #124 of the javafx-maven-plugin for further details.", ex); 100 | } 101 | } 102 | 103 | protected Map getFileSizes(List files) { 104 | final Map fileSizes = new HashMap<>(); 105 | files.stream().forEach(relativeFilePath -> { 106 | File file = new File(nativeOutputDir, relativeFilePath); 107 | // add the size for each file 108 | fileSizes.put(relativeFilePath, file.length()); 109 | }); 110 | return fileSizes; 111 | } 112 | 113 | public void fixFileSizesWithinGeneratedJNLPFiles() { 114 | // after signing, we have to adjust sizes, because they have changed (since they are modified with the signature) 115 | List jarFiles = getJARFilesFromJNLPFiles(); 116 | Map newFileSizes = getFileSizes(jarFiles); 117 | List generatedJNLPFiles = getGeneratedJNLPFiles(); 118 | Pattern pattern = Pattern.compile(JNLP_JAR_PATTERN); 119 | generatedJNLPFiles.forEach(file -> { 120 | try{ 121 | List allLines = Files.readAllLines(file.toPath()); 122 | List newLines = new ArrayList<>(); 123 | allLines.stream().forEach(line -> { 124 | if( line.matches(JNLP_JAR_PATTERN) ){ 125 | // get jar-file 126 | Matcher matcher = pattern.matcher(line); 127 | matcher.find(); 128 | String rawJarName = matcher.group(2); 129 | String jarName = rawJarName.substring(1, rawJarName.length() - 1); 130 | if( newFileSizes.containsKey(jarName) ){ 131 | // replace old size with new one 132 | newLines.add(line.replace(matcher.group(4), "\"" + newFileSizes.get(jarName) + "\"")); 133 | } else { 134 | newLines.add(line); 135 | } 136 | } else { 137 | newLines.add(line); 138 | } 139 | }); 140 | Files.write(file.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING); 141 | } catch(IOException ignored){ 142 | // NO-OP 143 | } 144 | }); 145 | } 146 | 147 | public List getGeneratedJNLPFiles() { 148 | List generatedFiles = new ArrayList<>(); 149 | 150 | // try-ressource, because walking on files is lazy, resulting in file-handler left open otherwise 151 | try(Stream walkstream = Files.walk(nativeOutputDir.toPath())){ 152 | walkstream.forEach(fileEntry -> { 153 | File possibleJNLPFile = fileEntry.toFile(); 154 | String fileName = possibleJNLPFile.getName(); 155 | if( fileName.endsWith(".jnlp") ){ 156 | generatedFiles.add(possibleJNLPFile); 157 | } 158 | }); 159 | } catch(IOException ignored){ 160 | // NO-OP 161 | } 162 | 163 | return generatedFiles; 164 | } 165 | 166 | public List getJARFilesFromJNLPFiles() { 167 | List jarFiles = new ArrayList<>(); 168 | getGeneratedJNLPFiles().stream().map(jnlpFile -> jnlpFile.toPath()).forEach(jnlpPath -> { 169 | try{ 170 | List allLines = Files.readAllLines(jnlpPath); 171 | allLines.stream().filter(line -> line.trim().startsWith(" generatedJNLPFiles = getGeneratedJNLPFiles(); 184 | Pattern pattern = Pattern.compile(JNLP_JAR_PATTERN); 185 | generatedJNLPFiles.forEach(file -> { 186 | try{ 187 | List allLines = Files.readAllLines(file.toPath()); 188 | List newLines = new ArrayList<>(); 189 | allLines.stream().forEach(line -> { 190 | if( line.matches(JNLP_JAR_PATTERN) ){ 191 | // get jar-file 192 | Matcher matcher = pattern.matcher(line); 193 | matcher.find(); 194 | String rawJarName = matcher.group(2); 195 | // replace \ with / 196 | newLines.add(line.replace(rawJarName, rawJarName.replaceAll("\\\\", "\\/"))); 197 | } else { 198 | newLines.add(line); 199 | } 200 | }); 201 | Files.write(file.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING); 202 | } catch(IOException ignored){ 203 | // NO-OP 204 | } 205 | }); 206 | } 207 | 208 | public void applyWorkaround124(String appName, List secondaryLaunchers) { 209 | // apply on main launcher 210 | applyNativeLauncherWorkaround(appName); 211 | 212 | // check on secondary launchers too 213 | if( secondaryLaunchers != null && !secondaryLaunchers.isEmpty() ){ 214 | secondaryLaunchers.stream().map(launcher -> { 215 | return launcher.getAppName(); 216 | }).filter(launcherAppName -> { 217 | // check appName containing any dots (which is the bug) 218 | return launcherAppName.contains("."); 219 | }).forEach(launcherAppname -> { 220 | applyNativeLauncherWorkaround(launcherAppname); 221 | }); 222 | } 223 | } 224 | 225 | public void applyWorkaround185(boolean skipSizeRecalculationForJNLP185) { 226 | if( !skipSizeRecalculationForJNLP185 ){ 227 | getLogger().info("Fixing sizes of JAR files within JNLP-files"); 228 | fixFileSizesWithinGeneratedJNLPFiles(); 229 | } else { 230 | getLogger().info("Skipped fixing sizes of JAR files within JNLP-files"); 231 | } 232 | } 233 | 234 | public void applyWorkaround167(Map params) { 235 | if( params.containsKey("runtime") ){ 236 | getLogger().info("Applying workaround for oracle-jdk-bug since 1.8.0u60 regarding cfg-file-format"); 237 | // the problem is com.oracle.tools.packager.windows.WinAppBundler within createLauncherForEntryPoint-Method 238 | // it does NOT respect runtime-setting while calling "writeCfgFile"-method of com.oracle.tools.packager.AbstractImageBundler 239 | // since newer java versions (they added possability to have INI-file-format of generated cfg-file, since 1.8.0_60). 240 | // Because we want to have backward-compatibility within java 8, we will use parameter-name as hardcoded string! 241 | // Our workaround: use prop-file-format 242 | params.put("launcher-cfg-format", "prop"); 243 | } 244 | } 245 | 246 | /* 247 | * Get generated, fixed cfg-files and push them to app-resources-list. 248 | */ 249 | public void applyWorkaround205(String appName, List secondaryLaunchers, Map params) { 250 | // to workaround, we are gathering the fixed versions of the previous executed "app-bundler" 251 | // and assume they all are existing 252 | Set filenameFixedConfigFiles = new HashSet<>(); 253 | 254 | // get cfg-file of main native launcher 255 | Path appPath = nativeOutputDir.toPath().resolve(appName).resolve("app").toAbsolutePath(); 256 | if( appName.contains(".") ){ 257 | String newConfigFileName = appName.substring(0, appName.lastIndexOf(".")); 258 | File mainAppNameCfgFile = appPath.resolve(newConfigFileName + CONFIG_FILE_EXTENSION).toFile(); 259 | if( mainAppNameCfgFile.exists() ){ 260 | getLogger().info("Found main native application configuration file (" + mainAppNameCfgFile.toString() + ")."); 261 | } 262 | filenameFixedConfigFiles.add(mainAppNameCfgFile); 263 | } 264 | 265 | // when having secondary native launchers, we need their cfg-files too 266 | Optional.ofNullable(secondaryLaunchers).ifPresent(launchers -> { 267 | launchers.stream().map(launcher -> { 268 | return launcher.getAppName(); 269 | }).forEach(secondaryLauncherAppName -> { 270 | if( secondaryLauncherAppName.contains(".") ){ 271 | String newSecondaryLauncherConfigFileName = secondaryLauncherAppName.substring(0, secondaryLauncherAppName.lastIndexOf(".")); 272 | filenameFixedConfigFiles.add(appPath.resolve(newSecondaryLauncherConfigFileName + CONFIG_FILE_EXTENSION).toFile()); 273 | } 274 | }); 275 | }); 276 | 277 | if( filenameFixedConfigFiles.isEmpty() ){ 278 | // it wasn't required to apply this workaround 279 | getLogger().info("No workaround for native launcher issue 205 needed. Continuing."); 280 | return; 281 | } 282 | getLogger().info("Applying workaround for native launcher issue 205 by modifying application resources."); 283 | 284 | // since 1.8.0_60 there exists some APP_RESOURCES_LIST, which contains multiple RelativeFileSet-instances 285 | // this is the more easy way ;) 286 | List appResourcesList = new ArrayList<>(); 287 | RelativeFileSet appResources = StandardBundlerParam.APP_RESOURCES.fetchFrom(params); 288 | // original application resources 289 | appResourcesList.add(appResources); 290 | // additional filename-fixed cfg-files 291 | appResourcesList.add(new RelativeFileSet(appPath.toFile(), filenameFixedConfigFiles)); 292 | 293 | // special workaround when having some jdk before update 60 294 | if( JavaDetectionTools.IS_JAVA_8 && !JavaDetectionTools.isAtLeastOracleJavaUpdateVersion(60) ){ 295 | try{ 296 | // pre-update60 did not contain any list of RelativeFileSets, which requires to rework APP_RESOURCES :/ 297 | Path tempResourcesDirectory = Files.createTempDirectory("jfxmp-workaround205-").toAbsolutePath(); 298 | File tempResourcesDirAsFile = tempResourcesDirectory.toFile(); 299 | getLogger().info("Modifying application resources for native launcher issue 205 by copying into temporary folder (" + tempResourcesDirAsFile.toString() + ")."); 300 | for( RelativeFileSet sources : appResourcesList ){ 301 | File baseDir = sources.getBaseDirectory(); 302 | for( String fname : appResources.getIncludedFiles() ){ 303 | IOUtils.copyFile(new File(baseDir, fname), new File(tempResourcesDirAsFile, fname)); 304 | } 305 | } 306 | 307 | // might not work for gradle, but maven does not hold up any JVM ;) 308 | // might rework this later into cleanup-phase 309 | tempResourcesDirAsFile.deleteOnExit(); 310 | 311 | // generate new RelativeFileSet with fixed cfg-file 312 | Set fixedResourceFiles = new HashSet<>(); 313 | try(Stream walkstream = Files.walk(tempResourcesDirectory)){ 314 | walkstream.map(p -> p.toFile()) 315 | .filter(File::isFile) 316 | .filter(File::canRead) 317 | .forEach(f -> { 318 | getLogger().info(String.format("Add %s file to application resources.", f)); 319 | fixedResourceFiles.add(f); 320 | }); 321 | } catch(IOException ignored){ 322 | // NO-OP 323 | } 324 | params.put(StandardBundlerParam.APP_RESOURCES.getID(), new RelativeFileSet(tempResourcesDirAsFile, fixedResourceFiles)); 325 | } catch(IOException ex){ 326 | getLogger().warn(null, ex); 327 | } 328 | return; 329 | } 330 | /* 331 | * Backward-compatibility note: 332 | * When using JDK 1.8.0u51 on travis-ci it would results into "cannot find symbol: variable APP_RESOURCES_LIST"! 333 | * 334 | * To solve this, we are using some hard-coded map-key :/ (please no hacky workaround via reflections .. urgh) 335 | */ 336 | params.put(StandardBundlerParam.APP_RESOURCES.getID() + "List", appResourcesList); 337 | } 338 | 339 | public boolean isWorkaroundForNativeMacBundlerNeeded(File additionalBundlerResources) { 340 | boolean isMac = System.getProperty("os.name").toLowerCase().contains("os x"); 341 | boolean hasBundlerResources = additionalBundlerResources != null && additionalBundlerResources.isDirectory() && additionalBundlerResources.exists(); 342 | 343 | return isMac && hasBundlerResources; 344 | } 345 | 346 | public Bundler applyWorkaroundForNativeMacBundler(final Bundler b, String currentRunningBundlerID, Map params, File additionalBundlerResources) { 347 | getLogger().info("Workaround for native mac bundler not present in this version (due to JDK9 compatibility conflicts)."); 348 | getLogger().info("Please use some older version of this plugin."); 349 | return b; 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers/JfxAbstractWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension; 19 | import java.io.BufferedReader; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.io.InputStreamReader; 24 | import java.lang.reflect.InvocationTargetException; 25 | import java.lang.reflect.Method; 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | import java.net.URLClassLoader; 29 | import java.nio.file.FileVisitResult; 30 | import java.nio.file.FileVisitor; 31 | import java.nio.file.Files; 32 | import java.nio.file.Path; 33 | import java.nio.file.StandardCopyOption; 34 | import java.nio.file.attribute.BasicFileAttributes; 35 | import java.util.function.Consumer; 36 | import org.gradle.api.GradleException; 37 | import org.gradle.api.Project; 38 | import org.gradle.api.logging.Logger; 39 | 40 | /** 41 | * 42 | * @author Danny Althoff 43 | */ 44 | public abstract class JfxAbstractWorker { 45 | 46 | protected void addDeployDirToSystemClassloader(Project project, JavaFXGradlePluginExtension ext) { 47 | // add deployDir to system classpath 48 | if( ext.getDeployDir() != null ){ 49 | 50 | File targetDeployDir = getAbsoluteOrProjectRelativeFile(project, ext.getDeployDir(), ext.isCheckForAbsolutePaths()); 51 | if( !targetDeployDir.exists() ){ 52 | project.getLogger().info("Adding 'deploy' directory wasn't successful, because it does not exist! (" + targetDeployDir.getAbsolutePath() + ")."); 53 | project.getLogger().info("You only need this directory when you want to override some resources."); 54 | return; 55 | } 56 | project.getLogger().info("Adding 'deploy' directory to classpath: " + ext.getDeployDir()); 57 | URLClassLoader sysloader = (URLClassLoader) this.getClass().getClassLoader(); 58 | Class sysclass = URLClassLoader.class; 59 | try{ 60 | Method method = sysclass.getDeclaredMethod("addURL", URL.class); 61 | method.setAccessible(true); 62 | method.invoke(sysloader, targetDeployDir.toURI().toURL()); 63 | } catch(NoSuchMethodException | SecurityException | MalformedURLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex){ 64 | throw new GradleException("Error, could not add URL to system classloader", ex); 65 | } 66 | } 67 | } 68 | 69 | protected boolean isGradleDaemonMode() { 70 | String javaCommand = System.getProperty("sun.java.command"); 71 | return javaCommand != null && javaCommand.startsWith("org.gradle.launcher.daemon"); 72 | } 73 | 74 | protected void redirectIO(Process p, Logger logger) { 75 | // when being on daemon-mode, we have to pipe it to the logger 76 | // @see https://github.com/FibreFoX/javafx-gradle-plugin/issues/29 77 | new StreamGobbler(p.getInputStream(), consumeInputLine -> { 78 | logger.lifecycle(consumeInputLine); 79 | }).run(); 80 | new StreamGobbler(p.getErrorStream(), consumeInputLine -> { 81 | logger.lifecycle(consumeInputLine); 82 | }).run(); 83 | } 84 | 85 | // http://stackoverflow.com/a/33386692/1961102 86 | protected class StreamGobbler implements Runnable { 87 | 88 | private InputStream inputStream; 89 | private Consumer consumeInputLine; 90 | 91 | public StreamGobbler(InputStream inputStream, Consumer consumeInputLine) { 92 | this.inputStream = inputStream; 93 | this.consumeInputLine = consumeInputLine; 94 | } 95 | 96 | @Override 97 | public void run() { 98 | new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumeInputLine); 99 | } 100 | } 101 | 102 | protected String getEnvironmentRelativeExecutablePath(boolean useEnvironmentRelativeExecutables) { 103 | if( useEnvironmentRelativeExecutables ){ 104 | return ""; 105 | } 106 | 107 | String jrePath = System.getProperty("java.home"); 108 | String jdkPath = jrePath + File.separator + ".." + File.separator + "bin" + File.separator; 109 | 110 | return jdkPath; 111 | } 112 | 113 | protected File getAbsoluteOrProjectRelativeFile(Project project, String potentialAbsoluteFilePath, boolean checkForAbsolutePaths) { 114 | File file = new File(potentialAbsoluteFilePath); 115 | if( file.isAbsolute() && checkForAbsolutePaths ){ 116 | return file; 117 | } 118 | return new File(project.getProjectDir(), potentialAbsoluteFilePath); 119 | } 120 | 121 | protected void copyRecursive(Path sourceFolder, Path targetFolder, Logger logger) throws IOException { 122 | Files.walkFileTree(sourceFolder, new FileVisitor() { 123 | 124 | @Override 125 | public FileVisitResult preVisitDirectory(Path subfolder, BasicFileAttributes attrs) throws IOException { 126 | // do create subfolder (if needed) 127 | Files.createDirectories(targetFolder.resolve(sourceFolder.relativize(subfolder))); 128 | return FileVisitResult.CONTINUE; 129 | } 130 | 131 | @Override 132 | public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { 133 | // do copy, and replace, as the resource might already be existing 134 | Files.copy(sourceFile, targetFolder.resolve(sourceFolder.relativize(sourceFile)), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); 135 | return FileVisitResult.CONTINUE; 136 | } 137 | 138 | @Override 139 | public FileVisitResult visitFileFailed(Path source, IOException ioe) throws IOException { 140 | // don't fail, just inform user 141 | logger.warn(String.format("Couldn't copy resource %s with reason %s", source.toString(), ioe.getLocalizedMessage())); 142 | return FileVisitResult.CONTINUE; 143 | } 144 | 145 | @Override 146 | public FileVisitResult postVisitDirectory(Path source, IOException ioe) throws IOException { 147 | // nothing to do here 148 | return FileVisitResult.CONTINUE; 149 | } 150 | }); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers/JfxGenerateKeystoreWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers; 17 | 18 | import com.oracle.tools.packager.Log; 19 | import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.nio.file.Files; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import org.gradle.api.GradleException; 26 | import org.gradle.api.Project; 27 | 28 | /** 29 | * 30 | * @author Danny Althoff 31 | */ 32 | public class JfxGenerateKeystoreWorker extends JfxAbstractWorker { 33 | 34 | @FunctionalInterface 35 | private interface RequiredFieldAlternativeCallback { 36 | 37 | String getValue(); 38 | } 39 | 40 | public void jfxgeneratekeystore(Project project) { 41 | // get our configuration 42 | JavaFXGradlePluginExtension ext = project.getExtensions().getByType(JavaFXGradlePluginExtension.class); 43 | addDeployDirToSystemClassloader(project, ext); 44 | 45 | // set logger-level 46 | Log.setLogger(new Log.Logger(ext.isVerbose())); 47 | 48 | File keyStore = getAbsoluteOrProjectRelativeFile(project, ext.getKeyStore(), ext.isCheckForAbsolutePaths()); 49 | 50 | if( keyStore.exists() ){ 51 | if( ext.isOverwriteKeyStore() ){ 52 | if( !keyStore.delete() ){ 53 | throw new GradleException("Unable to delete existing keystore at: " + keyStore); 54 | } 55 | } else { 56 | throw new GradleException("Keystore already exists (set 'overwriteKeyStore' to force) at: " + keyStore); 57 | } 58 | } 59 | 60 | checkKeystoreRequiredParameter(ext.getKeyStoreAlias(), "keyStoreAlias"); 61 | checkKeystoreRequiredParameter(ext.getKeyStorePassword(), "keyStorePassword"); 62 | 63 | if( ext.getKeyPassword() == null ){ 64 | ext.setKeyPassword(ext.getKeyStorePassword()); 65 | } 66 | 67 | List distinguishedNameParts = new ArrayList<>(); 68 | 69 | checkAndAddRequiredField(distinguishedNameParts, "certDomain", ext.getCertDomain(), "cn"); 70 | checkAndAddRequiredField(distinguishedNameParts, "certOrgUnit", ext.getCertOrgUnit(), "ou", () -> { 71 | return "none"; 72 | }); 73 | checkAndAddRequiredField(distinguishedNameParts, "certOrg", ext.getCertOrg(), "o"); 74 | checkAndAddRequiredField(distinguishedNameParts, "certState", ext.getCertState(), "st"); 75 | checkAndAddRequiredField(distinguishedNameParts, "certCountry", ext.getCertCountry(), "c"); 76 | 77 | generateKeyStore( 78 | project, keyStore, ext.getKeyStoreAlias(), ext.getKeyStorePassword(), ext.getKeyPassword(), String.join(", ", distinguishedNameParts), ext.isVerbose(), ext.isUseEnvironmentRelativeExecutables() 79 | ); 80 | } 81 | 82 | protected void generateKeyStore(Project project, File keyStore, String keyStoreAlias, String keyStorePassword, String keyPassword, String distinguishedName, boolean verbose, boolean useEnvironmentRelativeExecutables) { 83 | project.getLogger().info("Generating keystore in: " + keyStore); 84 | 85 | try{ 86 | // generated folder if it does not exist 87 | Files.createDirectories(keyStore.getParentFile().toPath()); 88 | 89 | List command = new ArrayList<>(); 90 | 91 | command.add(getEnvironmentRelativeExecutablePath(useEnvironmentRelativeExecutables) + "keytool"); 92 | command.add("-genkeypair"); 93 | command.add("-keystore"); 94 | command.add(keyStore.getPath()); 95 | command.add("-alias"); 96 | command.add(keyStoreAlias); 97 | command.add("-storepass"); 98 | command.add(keyStorePassword); 99 | command.add("-keypass"); 100 | command.add(keyPassword); 101 | command.add("-dname"); 102 | command.add(distinguishedName); 103 | command.add("-sigalg"); 104 | command.add("SHA256withRSA"); 105 | command.add("-validity"); 106 | command.add("100"); 107 | command.add("-keyalg"); 108 | command.add("RSA"); 109 | command.add("-keysize"); 110 | command.add("2048"); 111 | if( verbose ){ 112 | command.add("-v"); 113 | } 114 | 115 | ProcessBuilder pb = new ProcessBuilder(); 116 | if( !isGradleDaemonMode() ){ 117 | pb.inheritIO(); 118 | } 119 | 120 | if( verbose ){ 121 | project.getLogger().lifecycle("Running command: " + String.join(" ", command)); 122 | } 123 | 124 | pb.command(command); 125 | Process p = pb.start(); 126 | 127 | if( isGradleDaemonMode() ){ 128 | redirectIO(p, project.getLogger()); 129 | } 130 | 131 | p.waitFor(); 132 | } catch(IOException | InterruptedException ex){ 133 | throw new GradleException("There was an exception while generating keystore.", ex); 134 | } 135 | } 136 | 137 | private void checkKeystoreRequiredParameter(String value, String valueName) { 138 | if( value == null || value.trim().isEmpty() ){ 139 | throw new GradleException("The property '" + valueName + "' is required to generate a new KeyStore."); 140 | } 141 | } 142 | 143 | private void checkAndAddRequiredField(List distinguishedNameParts, String propertyName, String value, String fieldName) { 144 | checkAndAddRequiredField(distinguishedNameParts, propertyName, value, fieldName, null); 145 | } 146 | 147 | private void checkAndAddRequiredField(List distinguishedNameParts, String propertyName, String value, String fieldName, RequiredFieldAlternativeCallback alternative) { 148 | if( value != null && !value.trim().isEmpty() ){ 149 | distinguishedNameParts.add(fieldName + "=" + value); 150 | } else if( alternative == null || alternative.getValue() == null || alternative.getValue().trim().isEmpty() ){ 151 | throw new GradleException("The property '" + propertyName + "' must be provided to generate a new certificate."); 152 | } else { 153 | distinguishedNameParts.add(fieldName + "=" + alternative.getValue()); 154 | } 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers/JfxJarWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers; 17 | 18 | import com.oracle.tools.packager.Log; 19 | import com.sun.javafx.tools.packager.CreateJarParams; 20 | import com.sun.javafx.tools.packager.PackagerException; 21 | import com.sun.javafx.tools.packager.PackagerLib; 22 | import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension; 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.nio.file.FileVisitResult; 26 | import java.nio.file.Files; 27 | import java.nio.file.Path; 28 | import java.nio.file.SimpleFileVisitor; 29 | import java.nio.file.StandardCopyOption; 30 | import java.nio.file.attribute.BasicFileAttributes; 31 | import java.util.HashMap; 32 | import java.util.HashSet; 33 | import java.util.Map; 34 | import java.util.Optional; 35 | import java.util.Set; 36 | import org.gradle.api.GradleException; 37 | import org.gradle.api.Project; 38 | import org.gradle.api.artifacts.Configuration; 39 | import org.gradle.api.file.CopySpec; 40 | import org.gradle.api.specs.Specs; 41 | 42 | /** 43 | * 44 | * @author Danny Althoff 45 | */ 46 | public class JfxJarWorker extends JfxAbstractWorker { 47 | 48 | public void jfxjar(Project project) { 49 | // get our configuration 50 | JavaFXGradlePluginExtension ext = project.getExtensions().getByType(JavaFXGradlePluginExtension.class); 51 | addDeployDirToSystemClassloader(project, ext); 52 | 53 | // set logger-level 54 | Log.setLogger(new Log.Logger(ext.isVerbose())); 55 | 56 | // within maven we would get the jar-content inside some folder BEFORE it is out into JAR-file 57 | // within gradle we have to extract that folder to get all contents 58 | org.gradle.api.tasks.bundling.Jar jarTask = (org.gradle.api.tasks.bundling.Jar) project.getTasks().findByName("jar"); 59 | 60 | // within maven we would get the jar-content inside some folder BEFORE it is out into JAR-file 61 | // within gradle we have to extract that jar-file to get all contents inside a folder 62 | Path someTempDir; 63 | try{ 64 | someTempDir = Files.createTempDirectory("javafx-gradle-plugin"); 65 | } catch(IOException ex){ 66 | throw new GradleException("Couldn't create temporary folder", ex); 67 | } 68 | project.getLogger().info("Extraction of generated JAR-file ..."); 69 | project.copy((CopySpec copySpec) -> { 70 | copySpec.into(someTempDir.toFile()); 71 | if( ext.getAlternativePathToJarFile() == null ){ 72 | copySpec.from(project.zipTree(jarTask.getArchivePath())); 73 | } else { 74 | File alternativeJarFile = getAbsoluteOrProjectRelativeFile(project, ext.getAlternativePathToJarFile(), ext.isCheckForAbsolutePaths()); 75 | if( alternativeJarFile.exists() ){ 76 | copySpec.from(project.zipTree(alternativeJarFile)); 77 | } else { 78 | project.getLogger().warn("Could not find specified alternative JAR-file"); 79 | copySpec.from(project.zipTree(jarTask.getArchivePath())); 80 | } 81 | } 82 | }); 83 | 84 | project.getLogger().info("Creating parameter-map for packager..."); 85 | 86 | CreateJarParams createJarParams = new CreateJarParams(); 87 | createJarParams.setOutdir(getAbsoluteOrProjectRelativeFile(project, ext.getJfxAppOutputDir(), ext.isCheckForAbsolutePaths())); 88 | 89 | // check if we got some filename ending with ".jar" 90 | if( !ext.getJfxMainAppJarName().toLowerCase().endsWith(".jar") ){ 91 | throw new GradleException("Please provide a proper value for jfxMainAppJarName-property! It has to end with \".jar\"."); 92 | } 93 | createJarParams.setOutfile(ext.getJfxMainAppJarName()); 94 | createJarParams.setApplicationClass(ext.getMainClass()); 95 | createJarParams.setCss2bin(ext.isCss2bin()); 96 | createJarParams.setPreloader(ext.getPreLoader()); 97 | 98 | Map manifestAttributes = ext.getManifestAttributes(); 99 | if( manifestAttributes == null ){ 100 | manifestAttributes = new HashMap<>(); 101 | } 102 | createJarParams.setManifestAttrs(manifestAttributes); 103 | 104 | final File libDir = new File(getAbsoluteOrProjectRelativeFile(project, ext.getJfxAppOutputDir(), ext.isCheckForAbsolutePaths()), ext.getLibFolderName()); 105 | if( !libDir.exists() && !libDir.mkdirs() ){ 106 | throw new GradleException("Unable to create app lib dir: " + libDir); 107 | } 108 | 109 | if( ext.isUpdateExistingJar() ){ 110 | createJarParams.addResource(null, jarTask.getArchivePath()); 111 | } else { 112 | // produced and extracted jar-file 113 | createJarParams.addResource(someTempDir.toFile(), ""); 114 | } 115 | 116 | Set foundLibs = new HashSet<>(); 117 | 118 | // copy dependencies 119 | // got inspiration from: http://opensourceforgeeks.blogspot.de/2015/05/knowing-gradle-dependency-jars-download.html 120 | Configuration compileConfiguration = project.getConfigurations().getByName("compile"); 121 | if( !ext.isSkipCopyingDependencies() ){ 122 | copyModuleDependencies(compileConfiguration, "compile", project, libDir, foundLibs); 123 | copyFileDependencies(compileConfiguration, "compile", project, ext.isAddPackagerJar(), libDir, foundLibs); 124 | } else { 125 | project.getLogger().info("Skipped copying compile dependencies"); 126 | } 127 | 128 | Configuration runtimeConfiguration = project.getConfigurations().getByName("runtime"); 129 | if( !ext.isSkipCopyingDependencies() ){ 130 | copyModuleDependencies(runtimeConfiguration, "runtime", project, libDir, foundLibs); 131 | copyFileDependencies(runtimeConfiguration, "runtime", project, ext.isAddPackagerJar(), libDir, foundLibs); 132 | } else { 133 | project.getLogger().info("Skipped copying runtime dependencies"); 134 | } 135 | 136 | if( ext.isUseLibFolderContentForManifestClasspath() ){ 137 | StringBuilder scannedClasspath = new StringBuilder(); 138 | try{ 139 | Files.walkFileTree(libDir.toPath(), new SimpleFileVisitor() { 140 | @Override 141 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 142 | scannedClasspath.append(ext.getLibFolderName().replace("\\", "/")).append("/").append(libDir.toPath().relativize(file).toString().replace("\\", "/")).append(" "); 143 | return super.visitFile(file, attrs); 144 | } 145 | }); 146 | } catch(IOException ioex){ 147 | project.getLogger().warn("Got problem while scanning lib-folder", ioex); 148 | } 149 | createJarParams.setClasspath(scannedClasspath.toString()); 150 | } else { 151 | if( !foundLibs.isEmpty() ){ 152 | createJarParams.setClasspath(ext.getLibFolderName() + "/" + String.join(" " + ext.getLibFolderName() + "/", foundLibs)); 153 | } 154 | } 155 | Optional.ofNullable(ext.getFixedManifestClasspath()).ifPresent(manifestClasspath -> { 156 | if( manifestClasspath.trim().isEmpty() ){ 157 | return; 158 | } 159 | createJarParams.setClasspath(manifestClasspath); 160 | 161 | if( ext.isUseLibFolderContentForManifestClasspath() ){ 162 | project.getLogger().warn("You specified to use the content of the lib-folder AND specified a fixed classpath. The fixed classpath will get taken."); 163 | } 164 | }); 165 | 166 | // https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/manifest.html#JSDPG896 167 | if( ext.isAllPermissions() ){ 168 | manifestAttributes.put("Permissions", "all-permissions"); 169 | } 170 | 171 | PackagerLib packagerLib = new PackagerLib(); 172 | try{ 173 | project.getLogger().info("Running packager..."); 174 | packagerLib.packageAsJar(createJarParams); 175 | } catch(PackagerException ex){ 176 | throw new GradleException("Unable to build JFX JAR for application", ex); 177 | } 178 | 179 | if( ext.isCopyAdditionalAppResourcesToJar() ){ 180 | Optional.ofNullable(ext.getAdditionalAppResources()) 181 | .filter(appRessourcesString -> appRessourcesString != null) 182 | .map(appRessourcesString -> getAbsoluteOrProjectRelativeFile(project, appRessourcesString, ext.isCheckForAbsolutePaths())) 183 | .filter(File::exists) 184 | .ifPresent(appResources -> { 185 | project.getLogger().info("Copying additional app ressources..."); 186 | 187 | try{ 188 | Path targetFolder = getAbsoluteOrProjectRelativeFile(project, ext.getJfxAppOutputDir(), ext.isCheckForAbsolutePaths()).toPath(); 189 | Path sourceFolder = appResources.toPath(); 190 | copyRecursive(sourceFolder, targetFolder, project.getLogger()); 191 | } catch(IOException e){ 192 | project.getLogger().warn("Couldn't copy additional application resource-file(s).", e); 193 | } 194 | }); 195 | } 196 | 197 | // cleanup 198 | if( libDir.list().length == 0 ){ 199 | project.getLogger().info("Deleting unused lib-folder..."); 200 | // remove lib-folder, when nothing ended up there 201 | libDir.delete(); 202 | } 203 | 204 | // cleanup gradle-temp-folder 205 | // http://www.adam-bien.com/roller/abien/entry/java_7_deleting_recursively_a 206 | try{ 207 | Files.walkFileTree(someTempDir, new SimpleFileVisitor() { 208 | @Override 209 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 210 | Files.delete(file); 211 | return FileVisitResult.CONTINUE; 212 | } 213 | 214 | @Override 215 | public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { 216 | Files.delete(dir); 217 | return FileVisitResult.CONTINUE; 218 | } 219 | 220 | }); 221 | } catch(IOException iOException){ 222 | // ignored 223 | } 224 | } 225 | 226 | private void copyModuleDependencies(Configuration configuration, String toPrint, Project project, final File libDir, Set foundLibs) { 227 | project.getLogger().info("Copying defined " + toPrint + "-dependencies..."); 228 | // this will work for all non-file dependencies 229 | configuration.getResolvedConfiguration().getFirstLevelModuleDependencies().forEach(resolvedDep -> { 230 | // TODO add dependency-filter 231 | resolvedDep.getAllModuleArtifacts().forEach(artifact -> { 232 | try{ 233 | Path artifactPath = artifact.getFile().toPath(); 234 | String artifactFileName = artifactPath.getFileName().toString(); 235 | Files.copy(artifactPath, libDir.toPath().resolve(artifactFileName), StandardCopyOption.REPLACE_EXISTING); 236 | // will only append, when everything went right 237 | foundLibs.add(artifactFileName); 238 | } catch(IOException ex){ 239 | project.getLogger().warn("Couldn't copy dependency " + artifact.getId().getComponentIdentifier().toString(), ex); 240 | } 241 | }); 242 | }); 243 | } 244 | 245 | private void copyFileDependencies(Configuration configuration, String toPrint, Project project, boolean isPackagerJarToBeAdded, final File libDir, Set foundLibs) { 246 | project.getLogger().info("Copying defined " + toPrint + "-dependency-files..."); 247 | // inside "getFiles" all non-maven dependencies (like packager.jar) will be available 248 | configuration.getResolvedConfiguration().getFiles(Specs.SATISFIES_ALL).forEach(someFile -> { 249 | try{ 250 | Path artifactPath = someFile.toPath(); 251 | String artifactFileName = artifactPath.getFileName().toString(); 252 | if( "packager.jar".equals(artifactFileName) && !isPackagerJarToBeAdded ){ 253 | project.getLogger().info("Skipped adding packager.jar."); 254 | return; 255 | } 256 | 257 | // add this lib only, when not already present (could happen on file-dependencies ... which behaves different from maven-model) 258 | if( !foundLibs.contains(artifactFileName) ){ 259 | Files.copy(artifactPath, libDir.toPath().resolve(artifactFileName), StandardCopyOption.REPLACE_EXISTING); 260 | foundLibs.add(artifactFileName); 261 | } 262 | } catch(IOException ex){ 263 | project.getLogger().warn("Couldn't copy dependency " + someFile.getName(), ex); 264 | } 265 | }); 266 | } 267 | 268 | } 269 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers/JfxListBundlersWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers; 17 | 18 | import com.oracle.tools.packager.BundlerParamInfo; 19 | import com.oracle.tools.packager.Bundlers; 20 | import com.oracle.tools.packager.ConfigException; 21 | import com.oracle.tools.packager.UnsupportedPlatformException; 22 | import java.util.Collection; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | import java.util.Optional; 26 | import org.gradle.api.Project; 27 | import org.gradle.api.logging.LogLevel; 28 | import org.gradle.api.logging.Logger; 29 | 30 | /** 31 | * 32 | * @author Danny Althoff 33 | */ 34 | public class JfxListBundlersWorker extends JfxAbstractWorker { 35 | 36 | public void jfxlistbundlers(Project project) { 37 | Logger logger = project.getLogger(); 38 | 39 | Bundlers bundlers = Bundlers.createBundlersInstance(); 40 | logger.info("Available bundlers:"); 41 | logger.info("-------------------"); 42 | Map dummyParams = new HashMap<>(); 43 | bundlers.getBundlers().stream().forEach((bundler) -> { 44 | try{ 45 | bundler.validate(dummyParams); 46 | } catch(UnsupportedPlatformException ex){ 47 | return; 48 | } catch(ConfigException ex){ 49 | // NO-OP 50 | // bundler is supported on this OS 51 | } 52 | 53 | logger.lifecycle("ID: " + bundler.getID()); 54 | logger.lifecycle("Name: " + bundler.getName()); 55 | logger.lifecycle("Description: " + bundler.getDescription()); 56 | 57 | Collection> bundleParameters = bundler.getBundleParameters(); 58 | Optional.ofNullable(bundleParameters).ifPresent(nonNullBundleArguments -> { 59 | logger.info("Available bundle arguments: "); 60 | nonNullBundleArguments.stream().forEach(bundleArgument -> { 61 | logger.info("\t\tArgument ID: " + bundleArgument.getID()); 62 | logger.info("\t\tArgument Type: " + bundleArgument.getValueType().getName()); 63 | logger.info("\t\tArgument Name: " + bundleArgument.getName()); 64 | logger.info("\t\tArgument Description: " + bundleArgument.getDescription()); 65 | logger.info(""); 66 | }); 67 | }); 68 | logger.lifecycle("-------------------"); 69 | }); 70 | 71 | if( !logger.isEnabled(LogLevel.INFO) ){ 72 | logger.lifecycle("For more information, please use --info parameter."); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers/JfxRunWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers; 17 | 18 | import com.oracle.tools.packager.Log; 19 | import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension; 20 | import java.io.IOException; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Optional; 24 | import org.gradle.api.GradleException; 25 | import org.gradle.api.Project; 26 | 27 | /** 28 | * 29 | * @author Danny Althoff 30 | */ 31 | public class JfxRunWorker extends JfxAbstractWorker { 32 | 33 | public void jfxrun(Project project) { 34 | // get our configuration 35 | JavaFXGradlePluginExtension ext = project.getExtensions().getByType(JavaFXGradlePluginExtension.class); 36 | addDeployDirToSystemClassloader(project, ext); 37 | 38 | // set logger-level 39 | Log.setLogger(new Log.Logger(ext.isVerbose())); 40 | project.getLogger().lifecycle("Running JavaFX Application"); 41 | 42 | List command = new ArrayList<>(); 43 | command.add(getEnvironmentRelativeExecutablePath(ext.isUseEnvironmentRelativeExecutables()) + "java"); 44 | 45 | Optional.ofNullable(ext.getRunJavaParameter()).ifPresent(runJavaParameter -> { 46 | if( runJavaParameter.trim().isEmpty() ){ 47 | return; 48 | } 49 | command.add(runJavaParameter); 50 | }); 51 | 52 | Optional.ofNullable(ext.getRunJavaParameters()).ifPresent(runJavaParameters -> { 53 | if( runJavaParameters.isEmpty() ){ 54 | return; 55 | } 56 | command.addAll(runJavaParameters); 57 | }); 58 | 59 | command.add("-jar"); 60 | command.add(ext.getJfxMainAppJarName()); 61 | Optional.ofNullable(ext.getRunAppParameter()).ifPresent(runAppParameter -> { 62 | if( runAppParameter.trim().isEmpty() ){ 63 | return; 64 | } 65 | command.add(runAppParameter); 66 | }); 67 | 68 | try{ 69 | ProcessBuilder pb = new ProcessBuilder(); 70 | if( !isGradleDaemonMode() ){ 71 | pb.inheritIO(); 72 | } 73 | 74 | if( ext.isVerbose() ){ 75 | project.getLogger().lifecycle("Running command: " + String.join(" ", command)); 76 | } 77 | 78 | pb.directory(getAbsoluteOrProjectRelativeFile(project, ext.getJfxAppOutputDir(), ext.isCheckForAbsolutePaths())) 79 | .command(command); 80 | Process p = pb.start(); 81 | 82 | if( isGradleDaemonMode() ){ 83 | redirectIO(p, project.getLogger()); 84 | } 85 | 86 | p.waitFor(); 87 | if( p.exitValue() != 0 ){ 88 | throw new GradleException("There was an exception while executing JavaFX Application. Please check build-log."); 89 | } 90 | } catch(IOException | InterruptedException ex){ 91 | throw new GradleException("There was an exception while executing JavaFX Application.", ex); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/gradle-plugins/javafx-gradle-plugin.properties: -------------------------------------------------------------------------------- 1 | implementation-class=de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePlugin -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/AdditionalApplicationFiles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import static de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects.ExampleProjectTest.GRADLE_VERSIONS_TO_TEST_AGAINST; 19 | import static de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects.ExampleProjectTest.readVersionString; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.nio.file.Files; 23 | import java.nio.file.Path; 24 | import org.gradle.testkit.runner.BuildResult; 25 | import org.gradle.testkit.runner.GradleRunner; 26 | import org.testng.annotations.BeforeClass; 27 | import org.testng.annotations.Test; 28 | 29 | /** 30 | * 31 | * @author Danny Althoff 32 | */ 33 | public class AdditionalApplicationFiles extends ExampleProjectTest { 34 | 35 | @BeforeClass 36 | public static void readVersion() throws IOException { 37 | readVersionString(); 38 | } 39 | 40 | @Test 41 | public void additionalApplicationFilesJfxNative() { 42 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 43 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 44 | 45 | try{ 46 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-additionalApplicationFiles"); 47 | Path sourceFolder = new File("examples/additional-application-files").toPath(); 48 | // create copyto work on 49 | copyFolderRecursive(sourceFolder, targetFolder); 50 | 51 | writePluginVersionIntoBuildScript(targetFolder); 52 | 53 | // run build 54 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 55 | .withArguments("clean", "jfxNative", "--info", "--stacktrace") 56 | .withDebug(true) 57 | .build(); 58 | } catch(IOException e){ 59 | 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/AdditionalBundlerFiles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import static de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects.ExampleProjectTest.GRADLE_VERSIONS_TO_TEST_AGAINST; 19 | import static de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects.ExampleProjectTest.readVersionString; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.nio.file.Files; 23 | import java.nio.file.Path; 24 | import org.gradle.testkit.runner.BuildResult; 25 | import org.gradle.testkit.runner.GradleRunner; 26 | import org.testng.annotations.BeforeClass; 27 | import org.testng.annotations.Test; 28 | 29 | /** 30 | * 31 | * @author Danny Althoff 32 | */ 33 | public class AdditionalBundlerFiles extends ExampleProjectTest { 34 | 35 | @BeforeClass 36 | public static void readVersion() throws IOException { 37 | readVersionString(); 38 | } 39 | 40 | @Test 41 | public void additionalBundlerFilesJfxNative() { 42 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 43 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 44 | 45 | try{ 46 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-additionalBundlerFiles"); 47 | Path sourceFolder = new File("examples/additional-bundler-files").toPath(); 48 | // create copyto work on 49 | copyFolderRecursive(sourceFolder, targetFolder); 50 | 51 | writePluginVersionIntoBuildScript(targetFolder); 52 | 53 | // run build 54 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 55 | .withArguments("clean", "jfxNative", "--stacktrace") 56 | .withDebug(true) 57 | .build(); 58 | } catch(IOException e){ 59 | 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/ExampleProjectTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal.JavaDetectionTools; 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.nio.charset.StandardCharsets; 22 | import java.nio.file.FileVisitResult; 23 | import java.nio.file.FileVisitor; 24 | import java.nio.file.Files; 25 | import java.nio.file.Path; 26 | import java.nio.file.StandardCopyOption; 27 | import java.nio.file.StandardOpenOption; 28 | import java.nio.file.attribute.BasicFileAttributes; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import java.util.stream.Collectors; 32 | 33 | /** 34 | * 35 | * @author Danny Althoff 36 | */ 37 | public abstract class ExampleProjectTest { 38 | 39 | protected static final List GRADLE_VERSIONS_TO_TEST_AGAINST = new ArrayList<>(); 40 | 41 | static { 42 | if(JavaDetectionTools.IS_JAVA_8){ 43 | GRADLE_VERSIONS_TO_TEST_AGAINST.add("2.10"); 44 | GRADLE_VERSIONS_TO_TEST_AGAINST.add("3.0"); 45 | // this version removed "org.gradle.internal.classloader.ClasspathUtil" 46 | GRADLE_VERSIONS_TO_TEST_AGAINST.add("3.3"); 47 | } 48 | GRADLE_VERSIONS_TO_TEST_AGAINST.add("4.4.1"); 49 | } 50 | 51 | protected static String versionString = "+"; 52 | 53 | public static void readVersionString() throws IOException { 54 | List versionFileLines = Files.readAllLines(new File("version.gradle").toPath()); 55 | versionFileLines.forEach(line -> { 56 | if( line.contains("javafxGradlePluginVersion") ){ 57 | versionString = line.replace("javafxGradlePluginVersion", "").replace("=", "").replace("'", "").trim(); 58 | } 59 | }); 60 | } 61 | 62 | protected void writePluginVersionIntoBuildScript(Path targetFolder) throws IOException { 63 | // adjust the inclusion of version.gradle-file 64 | Path buildScript = targetFolder.resolve("build.gradle"); 65 | 66 | Files.write(buildScript, Files.readAllLines(buildScript).stream().map(line -> { 67 | // remove this, we are "hardcoding" our version 68 | if( "apply from: '../../version.gradle'".equals(line.trim()) ){ 69 | return ""; 70 | } 71 | if( line.endsWith("version: \"${gradle.javafxGradlePluginVersion}\"") ){ 72 | return line.replace("version: \"${gradle.javafxGradlePluginVersion}\"", "version: '" + versionString + "'"); 73 | } 74 | return line; 75 | }).collect(Collectors.toList()), StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING); 76 | } 77 | 78 | protected void copyFolderRecursive(Path sourceFolder, Path targetFolder) throws IOException { 79 | Files.walkFileTree(sourceFolder, new FileVisitor() { 80 | 81 | @Override 82 | public FileVisitResult preVisitDirectory(Path subfolder, BasicFileAttributes attrs) throws IOException { 83 | // do create subfolder (if needed) 84 | Files.createDirectories(targetFolder.resolve(sourceFolder.relativize(subfolder))); 85 | return FileVisitResult.CONTINUE; 86 | } 87 | 88 | @Override 89 | public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { 90 | // do copy 91 | Files.copy(sourceFile, targetFolder.resolve(sourceFolder.relativize(sourceFile)), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); 92 | return FileVisitResult.CONTINUE; 93 | } 94 | 95 | @Override 96 | public FileVisitResult visitFileFailed(Path source, IOException ioe) throws IOException { 97 | // don't fail, just inform user 98 | return FileVisitResult.CONTINUE; 99 | } 100 | 101 | @Override 102 | public FileVisitResult postVisitDirectory(Path source, IOException ioe) throws IOException { 103 | // nothing to do here 104 | return FileVisitResult.CONTINUE; 105 | } 106 | }); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/JavaFXProguardGradleExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal.JavaDetectionTools; 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.nio.file.Files; 22 | import java.nio.file.Path; 23 | import org.gradle.testkit.runner.BuildResult; 24 | import org.gradle.testkit.runner.GradleRunner; 25 | import static org.testng.Assert.assertTrue; 26 | import org.testng.annotations.BeforeClass; 27 | import org.testng.annotations.Test; 28 | 29 | /** 30 | * 31 | * @author Danny Althoff 32 | */ 33 | public class JavaFXProguardGradleExample extends ExampleProjectTest { 34 | 35 | @BeforeClass 36 | public static void readVersion() throws IOException { 37 | readVersionString(); 38 | } 39 | 40 | @Test 41 | public void javafxProguardGradleJfxJar() { 42 | if( JavaDetectionTools.IS_JAVA_9 ){ 43 | return; 44 | } 45 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 46 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 47 | 48 | try{ 49 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-javafxProguardGradle"); 50 | Path sourceFolder = new File("examples/javafx-proguard-gradle").toPath(); 51 | // create copyto work on 52 | copyFolderRecursive(sourceFolder, targetFolder); 53 | 54 | writePluginVersionIntoBuildScript(targetFolder); 55 | 56 | // run build 57 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 58 | .withArguments("clean", "jfxJar", "--stacktrace") 59 | .withDebug(true) 60 | .build(); 61 | } catch(IOException e){ 62 | 63 | } 64 | }); 65 | } 66 | 67 | @Test 68 | public void javafxProguardGradleJfxNative() { 69 | if( JavaDetectionTools.IS_JAVA_9 ){ 70 | return; 71 | } 72 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 73 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 74 | 75 | try{ 76 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-javafxProguardGradle"); 77 | Path sourceFolder = new File("examples/javafx-proguard-gradle").toPath(); 78 | // create copyto work on 79 | copyFolderRecursive(sourceFolder, targetFolder); 80 | 81 | writePluginVersionIntoBuildScript(targetFolder); 82 | 83 | // run build 84 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 85 | .withArguments("clean", "jfxNative", "--stacktrace") 86 | .withDebug(true) 87 | .build(); 88 | // check result 89 | 90 | // jar outcome 91 | assertTrue( 92 | Files.exists(targetFolder.resolve("build").resolve("libs").resolve("javafx-proguard-gradle.jar")) 93 | ); 94 | // myProguardTask outcome 95 | assertTrue( 96 | Files.exists(targetFolder.resolve("build").resolve("libs").resolve("javafx-proguard-gradle.out.jar")) 97 | ); 98 | // jfxJar outcome 99 | assertTrue( 100 | Files.exists(targetFolder.resolve("build").resolve("jfx").resolve("app").resolve("javafx-proguard-gradle-jfx.jar")) 101 | ); 102 | } catch(IOException e){ 103 | 104 | } 105 | }); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/MinimalProjectJfxJar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.nio.file.Files; 21 | import java.nio.file.Path; 22 | import org.gradle.testkit.runner.BuildResult; 23 | import org.gradle.testkit.runner.GradleRunner; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.Test; 26 | 27 | /** 28 | * 29 | * @author Danny Althoff 30 | */ 31 | public class MinimalProjectJfxJar extends ExampleProjectTest { 32 | 33 | @BeforeClass 34 | public static void readVersion() throws IOException { 35 | readVersionString(); 36 | } 37 | 38 | @Test 39 | public void minimalSetupJfxJar() { 40 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 41 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 42 | 43 | try{ 44 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-minimalSetupJfxJar"); 45 | Path sourceFolder = new File("examples/minimal-setup-jfxjar").toPath(); 46 | // create copyto work on 47 | copyFolderRecursive(sourceFolder, targetFolder); 48 | 49 | writePluginVersionIntoBuildScript(targetFolder); 50 | 51 | // run build 52 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 53 | .withArguments("clean", "jfxJar", "--stacktrace") 54 | .withDebug(true) 55 | .build(); 56 | // TODO check result (currently this is only a "runs without problems"-test) 57 | } catch(IOException e){ 58 | 59 | } 60 | }); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/MinimalProjectJfxNative.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.nio.file.Files; 21 | import java.nio.file.Path; 22 | import org.gradle.testkit.runner.BuildResult; 23 | import org.gradle.testkit.runner.GradleRunner; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.Test; 26 | 27 | /** 28 | * 29 | * @author Danny Althoff 30 | */ 31 | public class MinimalProjectJfxNative extends ExampleProjectTest { 32 | 33 | @BeforeClass 34 | public static void readVersion() throws IOException { 35 | readVersionString(); 36 | } 37 | 38 | @Test 39 | public void minimalSetupJfxNative() { 40 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 41 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 42 | 43 | try{ 44 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-minimalSetupJfxNative"); 45 | Path sourceFolder = new File("examples/minimal-setup-jfxnative").toPath(); 46 | // create copyto work on 47 | copyFolderRecursive(sourceFolder, targetFolder); 48 | 49 | writePluginVersionIntoBuildScript(targetFolder); 50 | 51 | // run build 52 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 53 | .withArguments("clean", "jfxNative", "--stacktrace") 54 | .withDebug(true) 55 | .build(); 56 | // TODO check result (currently this is only a "runs without problems"-test) 57 | } catch(IOException e){ 58 | 59 | } 60 | }); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/exampleprojects/MinimalProjectWithoutJre.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.exampleprojects; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.nio.file.Files; 21 | import java.nio.file.Path; 22 | import org.gradle.testkit.runner.BuildResult; 23 | import org.gradle.testkit.runner.GradleRunner; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.Test; 26 | 27 | /** 28 | * 29 | * @author Danny Althoff 30 | */ 31 | public class MinimalProjectWithoutJre extends ExampleProjectTest { 32 | 33 | @BeforeClass 34 | public static void readVersion() throws IOException { 35 | readVersionString(); 36 | } 37 | 38 | @Test 39 | public void minimalSetupJfxNative() { 40 | GRADLE_VERSIONS_TO_TEST_AGAINST.forEach(gradleVersion -> { 41 | GradleRunner runner = GradleRunner.create().withGradleVersion(gradleVersion).forwardOutput(); 42 | 43 | try{ 44 | Path targetFolder = Files.createTempDirectory("javafx-gradle-plugin-tests-" + this.getClass().getSimpleName() + "-minimalSetupWithoutJre"); 45 | Path sourceFolder = new File("examples/minimal-setup-without-bundled-jre").toPath(); 46 | // create copyto work on 47 | copyFolderRecursive(sourceFolder, targetFolder); 48 | 49 | writePluginVersionIntoBuildScript(targetFolder); 50 | 51 | // run build 52 | BuildResult buildResult = runner.withProjectDir(targetFolder.toAbsolutePath().toFile()) 53 | .withArguments("clean", "jfxNative", "--stacktrace") 54 | .withDebug(true) 55 | .build(); 56 | // TODO check result (currently this is only a "runs without problems"-test) 57 | } catch(IOException e){ 58 | 59 | } 60 | }); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/de/dynamicfiles/projects/gradle/plugins/javafx/tests/functional/SimpleApply.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Danny Althoff 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.dynamicfiles.projects.gradle.plugins.javafx.tests.functional; 17 | 18 | import org.gradle.api.Project; 19 | import org.gradle.api.artifacts.Dependency; 20 | import org.gradle.api.artifacts.dsl.DependencyHandler; 21 | import org.gradle.testfixtures.ProjectBuilder; 22 | import static org.testng.Assert.assertFalse; 23 | import static org.testng.Assert.assertTrue; 24 | import org.testng.annotations.Test; 25 | 26 | /** 27 | * 28 | * @author Danny Althoff 29 | */ 30 | public class SimpleApply { 31 | 32 | @Test 33 | public void testSimplePluginApply() { 34 | Project project = ProjectBuilder.builder().build(); 35 | DependencyHandler dependencyHandler = project.getDependencies(); 36 | Dependency pluginDependency = dependencyHandler.create("de.dynamicfiles.projects.gradle.plugins:javafx-gradle-plugin:+"); 37 | project.getBuildscript().getDependencies().add("classpath", pluginDependency); 38 | assertFalse(project.getPlugins().hasPlugin("java")); 39 | project.getPluginManager().apply("java"); 40 | assertTrue(project.getPlugins().hasPlugin("java")); 41 | assertFalse(project.getPlugins().hasPlugin("javafx-gradle-plugin")); 42 | project.getPluginManager().apply("javafx-gradle-plugin"); 43 | assertTrue(project.getPlugins().hasPlugin("javafx-gradle-plugin")); 44 | } 45 | 46 | @Test(expectedExceptions = org.gradle.api.GradleException.class) 47 | public void testSimplePluginApply_missingJavaPlugin() { 48 | Project project = ProjectBuilder.builder().build(); 49 | DependencyHandler dependencyHandler = project.getDependencies(); 50 | Dependency pluginDependency = dependencyHandler.create("de.dynamicfiles.projects.gradle.plugins:javafx-gradle-plugin:+"); 51 | project.getBuildscript().getDependencies().add("classpath", pluginDependency); 52 | assertFalse(project.getPlugins().hasPlugin("java")); 53 | assertFalse(project.getPlugins().hasPlugin("javafx-gradle-plugin")); 54 | project.getPluginManager().apply("javafx-gradle-plugin"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /version.gradle: -------------------------------------------------------------------------------- 1 | gradle.ext { 2 | javafxGradlePluginVersion = '8.9.0-SNAPSHOT' 3 | } 4 | --------------------------------------------------------------------------------