| ←Older revision |
Revision as of 07:01, 23 April 2022 |
| Line 4: |
Line 4: |
| | === Can I use [[Frgaal]] via {{JDK|javax/tools|ToolProvider}} [[API]]? === | | === Can I use [[Frgaal]] via {{JDK|javax/tools|ToolProvider}} [[API]]? === |
| | | | |
| - | Given following code (that invokes the {{JDK|javax/tool|JavaCompiler}} via {{JDK|javax/tool|ToolProvider}} for a custom ''CODE'' snippet that uses [[JDK]]17 {{JDK|java/lang|Record}}:
| + | Let's imagine we have a following code (that invokes the {{JDK|javax/tool|JavaCompiler}} via {{JDK|javax/tool|ToolProvider}} for a custom ''CODE'' snippet that uses [[JDK]]17 {{JDK|java/lang|Record}}: |
| | | | |
| | <source lang="java"> | | <source lang="java"> |
| Line 18: |
Line 18: |
| | | | |
| | class ModernJavaCompiler { | | class ModernJavaCompiler { |
| - | private static final String CODE = "record R (String name) {}"; | + | private static final String CODE = "record R (String name) {\n" |
| | + | + " public static void main(String... args) {\n" |
| | + | + " System.out.println(new R(\"Hello World!\"));\n" |
| | + | + " }\n" |
| | + | + "}\n"; |
| | | | |
| | public static void main(String... args) throws Exception { | | public static void main(String... args) throws Exception { |
| | JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler(); | | JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler(); |
| - | List<String> itrbl = Arrays.asList("-source", "17", "-target", "8"); | + | List<String> arguments = Arrays.asList(args); |
| - | List<String> itrbl1 = null;
| + | List<JavaFileObject> sources = Collections.singletonList(new Src(CODE)); |
| - | List<JavaFileObject> itrbl2 = Collections.singletonList(new Src(CODE)); | + | JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, arguments, null, sources); |
| - | JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, itrbl, itrbl1, itrbl2); | + | |
| | Boolean res = task.call(); | | Boolean res = task.call(); |
| | if (!Boolean.TRUE.equals(res)) { | | if (!Boolean.TRUE.equals(res)) { |
| Line 56: |
Line 59: |
| | </source> | | </source> |
| | | | |
| - | This is a Java class that can be compiled using | + | This is a regular Java source file that can be compiled using standard [[Javac]] compiler: |
| | | | |
| | <source lang="bash"> | | <source lang="bash"> |
| - | javac -source 8 -target 8 ModernJavaCompiler.java | + | $ javac -source 8 -target 8 ModernJavaCompiler.java |
| | </source> | | </source> |
| | | | |
| - | Then it can be executed on [[JDK]]-17 as
| + | The ''ModernJavaCompiler'' source code then uses {{JDK|javax/tool|JavaCompiler}} on its own to generate class ''R''. |
| | + | It can be executed [[JDK]]-17 as |
| | | | |
| | <source lang="bash"> | | <source lang="bash"> |
| | $ /jdk-17/bin/java ModernJavaCompiler | | $ /jdk-17/bin/java ModernJavaCompiler |
| | Compiled OK | | Compiled OK |
| | + | $ /jdk-17/bin/java R |
| | + | R[name=Hello World!] |
| | </source> | | </source> |
| | | | |
| - | However executing the same code on [[JDK]]-11 is going to fail (as the [[Javac]] from [[JDK]]-11 doesn't support -source 17): | + | However executing the same steps with [[JDK]]-11 is going to fail as the [[Javac]] from [[JDK]]-11 doesn't support '''record''' keyword: |
| | | | |
| | <source lang="bash"> | | <source lang="bash"> |
| | $ /jdk11/bin/java ModernJavaCompiler | | $ /jdk11/bin/java ModernJavaCompiler |
| - | Exception in thread "main" java.lang.IllegalArgumentException: error: invalid source release: 17
| + | Code.java:1: error: class, interface, or enum expected |
| - | at jdk.compiler/com.sun.tools.javac.main.Arguments.error(Arguments.java:907)
| + | record R (String name) { |
| - | at jdk.compiler/com.sun.tools.javac.main.Arguments.doProcessArgs(Arguments.java:383)
| + | ^ |
| - | at jdk.compiler/com.sun.tools.javac.main.Arguments.processArgs(Arguments.java:347)
| + | |
| - | at jdk.compiler/com.sun.tools.javac.main.Arguments.init(Arguments.java:246)
| + | |
| - | at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:185)
| + | |
| - | at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:119)
| + | |
| - | at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
| + | |
| - | at ModernJavaCompiler.main(ModernJavaCompiler.java:23)
| + | |
| | </source> | | </source> |
| | | | |
| - | The idea would be to replace the standard "compiler tool" with one coming from the [[frgaal]]. Let's try to disable the regular compiler first. There is an option '''--limit-modules''' in [[JDK]]-11+ and the idea is to use it to use it to disable standard [[JavaC]]: | + | The idea would be to replace the standard "compiler tool" with the one coming from the [[frgaal]] project. Let's try to disable the regular compiler first. There is an option '''--limit-modules''' in [[JDK]]-11+ and the idea is to use it to use it to disable standard [[JavaC]]: |
| | | | |
| | <source lang="bash"> | | <source lang="bash"> |
| Line 91: |
Line 91: |
| | </source> | | </source> |
| | | | |
| - | Great! The disabling works. The "compiler tool" is completely missing. Now there is a time to inject [[Frgaal]] instead. Following script shows how to get it all working: | + | Great! Disabling works. The "compiler tool" is completely missing. Now there is a time to inject [[Frgaal]] instead. Following script shows how to get it all working: |
| | | | |
| | <source lang="bash"> | | <source lang="bash"> |
| Line 102: |
Line 102: |
| | 2 warnings | | 2 warnings |
| | Compiled OK | | Compiled OK |
| | + | ~/bin/jdk-11/bin/java R |
| | + | R[name=Hello World!] |
| | </source> | | </source> |
| | | | |
| - | E.g. it is necessary to provide extra {{JDK|java/util|ServiceLoader}} registration in ''META-INF/services'' path on the class path, but then it seems to run. Embed [[Frgaal]] into your own programs and use the latest [[Java]] features on any [[JDK]]!
| + | Hey, using '''record''' on JDK-11! |
| | + | |
| | + | Having '''record''' (and other [[JDK]]-18 language features) available on old JDKs is great, isn't it? All that is necessary is to provide extra {{JDK|java/util|ServiceLoader}} registration in ''META-INF/services'' path on the class path. Then the [[Frgaal]] compiler gets picked up and is used for compilation even on older [[JDK]]s. |
| | + | |
| | + | |
| | + | Embed [[Frgaal]] into your own programs and use the latest [[Java]] features on any [[JDK]]! |