Added support for Java 8 features (not yet utilized)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/9df633ca Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/9df633ca Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/9df633ca Branch: refs/heads/2.3 Commit: 9df633caaec0a594a4496890c8ae9b7b62778740 Parents: 5ca7e14 Author: ddekany <[email protected]> Authored: Tue Mar 7 15:11:12 2017 +0100 Committer: ddekany <[email protected]> Committed: Tue Mar 7 15:11:12 2017 +0100 ---------------------------------------------------------------------- README | 6 +-- build.properties.sample | 1 + build.xml | 33 ++++++++++++-- src/main/java/freemarker/core/_Java6Impl.java | 2 + src/main/java/freemarker/core/_Java8.java | 34 +++++++++++++++ src/main/java/freemarker/core/_Java8Impl.java | 23 ++++++++++ .../java/freemarker/core/_JavaVersions.java | 45 ++++++++++++++++++++ 7 files changed, 137 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/README ---------------------------------------------------------------------- diff --git a/README b/README index 8fa6e07..d5ab3b7 100644 --- a/README +++ b/README @@ -167,7 +167,7 @@ apply it to your development environment: Number of imports required for .*: 99 Number of static imports needed for .*: 1 - Java -> Installed JRE-s: - Ensure that you have JDK 6 installed, and that it was added to Eclipse. + Ensure that you have JDK 8 installed, and that it was added to Eclipse. Note that it's not JRE, but JDK. - Java -> Compiler -> Javadoc: "Malformed Javadoc comments": Error @@ -190,7 +190,7 @@ apply it to your development environment: src/test/resources - On the "Libraries" tab: - Delete everyhing from there, except the "JRE System Library [...]" - - Edit "JRE System Library [...]" to "Execution Environment" "JavaSE 1.6" + - Edit "JRE System Library [...]" to "Execution Environment" "JavaSE 1.8" - Add all jar-s that are directly under the "ide-dependencies" directory (use the "Add JARs..." and select all those files). - On the "Order and Export" tab find dom4j-*.jar, and send it to the @@ -207,7 +207,7 @@ apply it to your development environment: - You will still have errors on these java files (because different java files depend on different versions of the same library, and Eclipse can't handle that). Exclude those java files from the Build Path (in the Package - Explorer, right click on the problematic file -> "Build Path" -> "Exclude"). + Explorer, right click on the problematic file -> "Build Path" -> "Exclude"): _Jython20*.java _Jython22*.java _FreeMarkerPageContext2.java http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/build.properties.sample ---------------------------------------------------------------------- diff --git a/build.properties.sample b/build.properties.sample index c5dc8ff..56315b3 100644 --- a/build.properties.sample +++ b/build.properties.sample @@ -19,5 +19,6 @@ # These propeties should point to the rt.jar-s of the respective J2SE versions: boot.classpath.j2se1.5=C:/Program Files (x86)/Java/jdk1.5.0_16/jre/lib/rt.jar boot.classpath.j2se1.6=C:/Program Files/Java/jdk1.6.0_24/jre/lib/rt.jar +boot.classpath.j2se1.8=C:/Program Files/Java/jdk1.8.0_66/jre/lib/rt.jar mvnCommand=C:/Program Files (x86)/maven3/bin/mvn.bat gpgCommand=C:/Program Files (x86)/GNU/GnuPG/pub/gpg.exe \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/build.xml ---------------------------------------------------------------------- diff --git a/build.xml b/build.xml index 9b29946..4e1f979 100644 --- a/build.xml +++ b/build.xml @@ -49,10 +49,14 @@ <condition property="has.explicit.boot.classpath.j2se1.6"> <isset property="boot.classpath.j2se1.6"/> </condition> + <condition property="has.explicit.boot.classpath.j2se1.8"> + <isset property="boot.classpath.j2se1.8"/> + </condition> <condition property="has.all.explicit.boot.classpaths"> <and> <isset property="has.explicit.boot.classpath.j2se1.5"/> <isset property="has.explicit.boot.classpath.j2se1.6"/> + <isset property="has.explicit.boot.classpath.j2se1.8"/> </and> </condition> <available property="atLeastJDK8" classname="java.util.function.Predicate"/> @@ -61,6 +65,7 @@ <!-- Note: Target "dist" doesn't allow using these. --> <property name="boot.classpath.j2se1.5" value="${sun.boot.class.path}" /> <property name="boot.classpath.j2se1.6" value="${sun.boot.class.path}" /> + <property name="boot.classpath.j2se1.8" value="${sun.boot.class.path}" /> <!-- For checking the correctness of the boot.classpath.j2se* --> <available classpath="${boot.classpath.j2se1.5}" @@ -71,6 +76,10 @@ classname="java.util.ServiceLoader" ignoresystemclasses="true" property="boot.classpath.j2se1.6.correct" /> + <available classpath="${boot.classpath.j2se1.8}" + classname="java.time.Instant" ignoresystemclasses="true" + property="boot.classpath.j2se1.8.correct" + /> <!-- Set up version/timestamp filters and the version property: --> <tstamp> @@ -207,10 +216,17 @@ -->the <projectDir>/build.properties file, or wherever you <!-- -->set it.<!-- --></fail> + <fail unless="boot.classpath.j2se1.8.correct"><!-- + -->The "boot.classpath.j2se1.8" property value (${boot.classpath.j2se1.8}) <!-- + -->seems to be an incorrect boot classpath. Please fix it in <!-- + -->the <projectDir>/build.properties file, or wherever you <!-- + -->set it.<!-- + --></fail> <echo level="info"><!-- -->Using boot classpaths:<!-- -->Java 5: ${boot.classpath.j2se1.5}; <!-- -->Java 6: ${boot.classpath.j2se1.6}<!-- + -->Java 8: ${boot.classpath.j2se1.8}<!-- --></echo> <!-- Comment out @SuppressFBWarnings, as it causes compilation warnings in dependent Gradle projects --> @@ -242,7 +258,7 @@ classpathref="ivy.dep" bootclasspath="${boot.classpath.j2se1.5}" excludes=" - freemarker/core/_Java6Impl.java, + freemarker/core/_Java?*Impl.java, freemarker/ext/jsp/**, freemarker/ext/servlet/**, freemarker/cache/WebappTemplateLoader.java, @@ -259,12 +275,21 @@ <ivy:cachepath conf="build.base" pathid="ivy.dep" /> <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" - debug="on" optimize="off" target="1.5" source="1.5" encoding="utf-8" + debug="on" optimize="off" target="1.6" source="1.6" encoding="utf-8" includeantruntime="false" classpathref="ivy.dep" bootclasspath="${boot.classpath.j2se1.6}" includes="freemarker/core/_Java6Impl.java" /> + + <ivy:cachepath conf="build.base" pathid="ivy.dep" /> + <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" + debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8" + includeantruntime="false" + classpathref="ivy.dep" + bootclasspath="${boot.classpath.j2se1.8}" + includes="freemarker/core/_Java8Impl.java" + /> <rmic base="build/classes" includes="freemarker/debug/impl/Rmi*Impl.class" @@ -376,11 +401,11 @@ <ivy:cachepath conf="build.test" pathid="ivy.dep.build.test" /> <javac srcdir="src/test/java" destdir="build/test-classes" deprecation="off" - debug="on" optimize="off" target="1.5" source="1.5" encoding="utf-8" + debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8" includeantruntime="false" classpath="build/classes" classpathref="ivy.dep.build.test" - bootclasspath="${boot.classpath.j2se1.6}" + bootclasspath="${boot.classpath.j2se1.8}" /> <copy toDir="build/test-classes"> <fileset dir="src/test/resources" http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java6Impl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/_Java6Impl.java b/src/main/java/freemarker/core/_Java6Impl.java index 05c1258..090a58d 100644 --- a/src/main/java/freemarker/core/_Java6Impl.java +++ b/src/main/java/freemarker/core/_Java6Impl.java @@ -26,6 +26,8 @@ import java.text.DecimalFormatSymbols; * Used internally only, might changes without notice! * Used for accessing functionality that's only present in Java 6 or later. */ +//Compile this against Java 6 +@SuppressWarnings("Since15") // For IntelliJ inspection public final class _Java6Impl implements _Java6 { public static final _Java6 INSTANCE = new _Java6Impl(); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java8.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/_Java8.java b/src/main/java/freemarker/core/_Java8.java new file mode 100644 index 0000000..34979da --- /dev/null +++ b/src/main/java/freemarker/core/_Java8.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package freemarker.core; + +import java.lang.reflect.Method; + +/** + * Used internally only, might changes without notice! + * Used for accessing functionality that's only present in Java 8 or later. + */ +public interface _Java8 { + + /** + * Returns if it's a Java 8 "default method". + */ + boolean isDefaultMethod(Method method); + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java8Impl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/_Java8Impl.java b/src/main/java/freemarker/core/_Java8Impl.java new file mode 100644 index 0000000..fe9bb07 --- /dev/null +++ b/src/main/java/freemarker/core/_Java8Impl.java @@ -0,0 +1,23 @@ +package freemarker.core; + +import java.lang.reflect.Method; + +/** + * Used internally only, might changes without notice! + * Used for accessing functionality that's only present in Java 6 or later. + */ +// Compile this against Java 8 +@SuppressWarnings("Since15") // For IntelliJ inspection +public class _Java8Impl implements _Java8 { + + public static final _Java8 INSTANCE = new _Java8Impl(); + + private _Java8Impl() { + // Not meant to be instantiated + } + + public boolean isDefaultMethod(Method method) { + return method.isDefault(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_JavaVersions.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/_JavaVersions.java b/src/main/java/freemarker/core/_JavaVersions.java index 1101752..7e6f1eb 100644 --- a/src/main/java/freemarker/core/_JavaVersions.java +++ b/src/main/java/freemarker/core/_JavaVersions.java @@ -74,4 +74,49 @@ public final class _JavaVersions { JAVA_6 = java6; } + private static final boolean IS_AT_LEAST_8; + static { + boolean result = false; + String vStr = SecurityUtilities.getSystemProperty("java.version", null); + if (vStr != null) { + try { + Version v = new Version(vStr); + result = v.getMajor() == 1 && v.getMinor() >= 8 || v.getMajor() > 1; + } catch (Exception e) { + // Ignore + } + } else { + try { + Class.forName("java.time.Instant"); + result = true; + } catch (Exception e) { + // Ignore + } + } + IS_AT_LEAST_8 = result; + } + + /** + * {@code null} if Java 8 is not available, otherwise the object through with the Java 8 operations are available. + */ + static public final _Java8 JAVA_8; + static { + _Java8 java8; + if (IS_AT_LEAST_8) { + try { + java8 = (_Java8) Class.forName("freemarker.core._Java8Impl").getField("INSTANCE").get(null); + } catch (Exception e) { + try { + Logger.getLogger("freemarker.runtime").error("Failed to access Java 8 functionality", e); + } catch (Exception e2) { + // Suppressed + } + java8 = null; + } + } else { + java8 = null; + } + JAVA_8 = java8; + } + }
