├── .gitignore ├── LICENSE ├── README.md ├── executable ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── codefx │ └── demo │ └── mvn_java9 │ └── Main.java ├── mavenrc ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── codefx │ └── demo │ └── mvn_java9 │ └── Main.java └── toolchain ├── README.md ├── pom.xml └── src └── main └── java └── org └── codefx └── demo └── mvn_java9 └── Main.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maven Java 9 2 | 3 | Different ways to build projects on Java 9 with Maven. 4 | The goal is to be able to simply run `mvn clean install` and then launch the resulting JAR with `java -jar target/demo-java-9.jar`. 5 | 6 | * [``](executable) 7 | * [.mavenrc](mavenrc) 8 | * [toolchain](toolchain) 9 | 10 | Some approaches are more intrusive, others more brittle - have a look at the individual solutions for a small discussion of its pros and cons. 11 | 12 | ## 💥 Compiler Arguments 💥 13 | 14 | In case you're trying to use some of the new command line options like `--add-modules`, be aware that the following doesn't work: 15 | 16 | ```xml 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.6.1 21 | 22 | 23 | --add-modules java.xml.bind 24 | 25 | true 26 | 27 | 28 | ``` 29 | 30 | With this configuration I got errors like the following: 31 | 32 | ``` 33 | [INFO] ------------------------------------------------------------- 34 | [ERROR] COMPILATION ERROR : 35 | [INFO] ------------------------------------------------------------- 36 | [ERROR] javac: invalid flag: --add-modules java.xml.bind 37 | Usage: javac 38 | use --help for a list of possible options 39 | ``` 40 | 41 | Apparently [it's common knowledge](https://twitter.com/rfscholte/status/849969556332437504) that `` will put arguments that contain a space into quotes before passing them, so I had to do the following instead: 42 | 43 | ```xml 44 | 45 | --add-modulesjava.xml.bind 46 | 47 | ``` 48 | 49 | Obvious, right? 🤔 50 | -------------------------------------------------------------------------------- /executable/README.md: -------------------------------------------------------------------------------- 1 | # Executable 2 | 3 | In the `maven-compiler-plugin` the executable to be used for compilation [can be explicitly named](https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#executable): 4 | 5 | ```xml 6 | 7 | 8 | 9 | 10 | org.apache.maven.plugins 11 | maven-compiler-plugin 12 | 3.6.1 13 | 14 | 1.9 15 | 1.9 16 | 9 17 | 18 | true 19 | javac9 20 | 21 | 22 | 23 | 24 | ``` 25 | 26 | For `executable` to have an effect, [the `fork` option](https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#fork) needs to be set to `true`, which tells Maven to launch the compiler in a separate process. 27 | 28 | ## Improvements 29 | 30 | In the example above I simply use `javac9`. 31 | That works for me because I symlinked `/bin/javac9` (as well as `java9`, `jar9`, `jdeps9`) to `/opt/jdk-9/bin/javac` and `/opt/jdk-9` to whatever JDK 9 EA build I am currently using (e.g. `/opt/jdk-9-b163`). 32 | Your and your team's setup might differ of course an there are two ways to improve this. 33 | 34 | ### Command Line Option 35 | 36 | If you are just experimenting you could consider specifying the property on the command line instead: 37 | 38 | ``` 39 | mvn -Dmaven.compiler.fork -Dmaven.compiler.executable=javac9 clean install 40 | ``` 41 | 42 | This _only_ works if you do not also set it in ``, though. 43 | 44 | ### `settings.xml` 45 | 46 | To make the compiler change less static, you can use a self-defined user property and ask developers to define it in their `settings.xml`. 47 | See [the Maven docs](https://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html) for more on that. 48 | 49 | ## Pros and Cons 50 | 51 | To compile with Java 9, for example to check whether your project builds without errors, the command line flag is a low ceremony approach as it requires no other changes (assuming you do not already specify the executable in ``). 52 | 53 | If you not only want to compile with Java 9 but also use Java 9 features, you still have to specify the target `1.9`. 54 | This starts bloating the command line. 55 | If you put it into the pom, consider referencing the executable relative to some property, every developer has to set. 56 | But if you're going down that road, why not use the [toolchain](../toolchain)? 57 | -------------------------------------------------------------------------------- /executable/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.codefx.demo.mvn-java-9 8 | demo 9 | java-9 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 3.6.1 18 | 19 | 9 20 | javac9 21 | true 22 | 23 | 24 | 25 | 26 | org.apache.maven.plugins 27 | maven-jar-plugin 28 | 3.0.2 29 | 30 | 31 | 32 | true 33 | org.codefx.demo.mvn_java9.Main 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /executable/src/main/java/org/codefx/demo/mvn_java9/Main.java: -------------------------------------------------------------------------------- 1 | package org.codefx.demo.mvn_java9; 2 | 3 | import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; 4 | 5 | public class Main { 6 | 7 | public static void main(String[] args) { 8 | printCallerClass(); 9 | } 10 | 11 | private static void printCallerClass() { 12 | Class callerClass = StackWalker 13 | .getInstance(RETAIN_CLASS_REFERENCE) 14 | .getCallerClass(); 15 | System.out.println(callerClass); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mavenrc/README.md: -------------------------------------------------------------------------------- 1 | # `mavenrc` 2 | 3 | Maven can apparently be configured with the [mostly undocumented](https://issues.apache.org/jira/browse/MNGSITE-246) files `~/.mavenrc` (for current user) and `/etc/mavenrc` (for all users). 4 | In there, environment variables and command line options for the Java command can be configured. 5 | 6 | With this, it is easy to set `JAVA_HOME` just for the Maven command, which will lead to it running with the specified version. 7 | Here's the content of that file: 8 | 9 | ``` 10 | JAVA_HOME="/path/to/your/jdk-9" 11 | ``` 12 | 13 | ## Pros and Cons 14 | 15 | To compile with Java 9, for example to check whether your project builds without errors, this is a low ceremony approach as it requires no other changes. 16 | 17 | If you not only want to compile with Java 9 but also use Java 9 features, you still have to specify `9` in your [pom](pom.xml). 18 | Note that this puts the pom into an awkward state where it is supposed to use JDK 9 but does not reference where it might come from (unlike the [toolchain approach](../toolchain)). 19 | Another disadvantage is that it must be repeated for every developer on the project. 20 | -------------------------------------------------------------------------------- /mavenrc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.codefx.demo.mvn-java-9 8 | demo 9 | java-9 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 3.6.1 18 | 19 | 9 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-jar-plugin 26 | 3.0.2 27 | 28 | 29 | 30 | true 31 | org.codefx.demo.mvn_java9.Main 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /mavenrc/src/main/java/org/codefx/demo/mvn_java9/Main.java: -------------------------------------------------------------------------------- 1 | package org.codefx.demo.mvn_java9; 2 | 3 | import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; 4 | 5 | public class Main { 6 | 7 | public static void main(String[] args) { 8 | printCallerClass(); 9 | } 10 | 11 | private static void printCallerClass() { 12 | Class callerClass = StackWalker 13 | .getInstance(RETAIN_CLASS_REFERENCE) 14 | .getCallerClass(); 15 | System.out.println(callerClass); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /toolchain/README.md: -------------------------------------------------------------------------------- 1 | # Toolchain 2 | 3 | Using [Maven Toolchains][mvn-toolchains] it is easy to define Java 9 in the project's `pom.xml` and let every developer specify their path via the toolchain. 4 | 5 | Have a look at [the pom](pom.xml) and put this into `~/.m2/toolchains.xml`: 6 | 7 | ```xml 8 | 9 | 10 | 11 | jdk 12 | 13 | 1.9 14 | oracle 15 | 16 | 17 | /path/to/your/jdk-9 18 | 19 | 20 | 21 | jdk 22 | 23 | 1.8 24 | oracle 25 | 26 | 27 | /path/to/your/jdk-8 28 | 29 | 30 | 31 | ``` 32 | 33 | ## Pros and Cons 34 | 35 | This is arguably the cleanest approach because it is project-specific and makes obvious in the pom where the Java 9 compiler is supposed to come from. 36 | 37 | It requires mucking with the pom, though, which in large legacy projects might not be your first choice. 38 | For a less intrusive way to build on Java 9, look at [the alternatives](..). 39 | 40 | [mvn-toolchains]: https://maven.apache.org/guides/mini/guide-using-toolchains.html 41 | -------------------------------------------------------------------------------- /toolchain/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.codefx.demo.mvn-java-9 8 | demo 9 | java-9 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 3.6.1 18 | 19 | 9 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-toolchains-plugin 26 | 1.1 27 | 28 | 29 | 30 | 1.9 31 | oracle 32 | 33 | 34 | 35 | 36 | 37 | 38 | toolchain 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.apache.maven.plugins 46 | maven-jar-plugin 47 | 3.0.2 48 | 49 | 50 | 51 | true 52 | org.codefx.demo.mvn_java9.Main 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /toolchain/src/main/java/org/codefx/demo/mvn_java9/Main.java: -------------------------------------------------------------------------------- 1 | package org.codefx.demo.mvn_java9; 2 | 3 | import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; 4 | 5 | public class Main { 6 | 7 | public static void main(String[] args) { 8 | printCallerClass(); 9 | } 10 | 11 | private static void printCallerClass() { 12 | Class callerClass = StackWalker 13 | .getInstance(RETAIN_CLASS_REFERENCE) 14 | .getCallerClass(); 15 | System.out.println(callerClass); 16 | } 17 | 18 | } 19 | --------------------------------------------------------------------------------