You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2020/04/11 08:29:59 UTC

[freemarker] 02/02: Switched to Java 8 as minimum requirement. It's not feasible to support Java 8 time API otherwise, since it's statically referred from TemplateTemporalModel.

This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch FREEMARKER-35
in repository https://gitbox.apache.org/repos/asf/freemarker.git

commit e3e3185f2f53205e1c2a91e094de145d626e23ff
Author: ddekany <dd...@apache.org>
AuthorDate: Sat Apr 11 10:27:46 2020 +0200

    Switched to Java 8 as minimum requirement. It's not feasible to support Java 8 time API otherwise, since it's statically referred from TemplateTemporalModel.
---
 README.md                                          |  7 +-
 build.properties.sample                            |  1 -
 build.xml                                          | 48 ++++---------
 osgi.bnd                                           |  8 +--
 src/main/java/freemarker/core/_Java8Impl.java      | 42 ------------
 src/main/java/freemarker/core/_JavaVersions.java   | 79 ----------------------
 .../freemarker/ext/beans/ClassIntrospector.java    |  9 ++-
 .../freemarker/ext/beans/BeansWrapperMiscTest.java |  2 -
 8 files changed, 21 insertions(+), 175 deletions(-)

diff --git a/README.md b/README.md
index d8197cb..b764b84 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ dependency, as freemarker.ext.dom can't use the XPath support
 included in OpenJDK anymore. It's not needed on Oracle Java 9,
 or if FreeMarker is configured to use Jaxen for XPath.
 
-The minimum required Java version is currently Java SE 7. (The presence
+The minimum required Java version is currently Java SE 8. (The presence
 of a later version may be detected on runtime and utilized by
 FreeMarker.)
 
@@ -201,8 +201,6 @@ Below you find the step-by-step setup for Eclipse (originally done on Mars.1):
    - Press "Finish"
 - Eclipse will indicate many errors at this point; it's expected, read on.
 - Project -> Properties -> Java Compiler
-  - Set "Compiler Compliance Level" to "1.7" (you will have to uncheck
-    "Use compliance from execution environment" for that)
   - In Errors/Warnings, check in "Enable project specific settings", then set
     "Forbidden reference (access rules)" from "Error" to "Warning".
 - You will still have errors on these java files (because different java
@@ -272,9 +270,6 @@ Originally done on IntelliJ IDEA Community 2018.2.4:
     - Test Resource Folders:  
       src/test/resources
       
-  - Still inside the "Sources" tab, change the "Language level" to "7". (Yes, we use Java 8 SDK with
-    language level 7 in the IDE, due to the tricks FreeMarker uses to support different Java versions.)
-    
   - Switch over to the "Dependencies" tab (still inside "Project Structure" / "Modules"), and add
     all the jar-s inside the `ide-dependencies` directory as dependency. (How: Click the "+" icon
     at the right edge, select "JARs or directory", navigate to `ide-dependencies` directory, expand
diff --git a/build.properties.sample b/build.properties.sample
index d5e31cc..49eb98f 100644
--- a/build.properties.sample
+++ b/build.properties.sample
@@ -17,7 +17,6 @@
 
 # Copy this file to "build.properties" before editing!
 # These propeties should point to the rt.jar-s of the respective J2SE versions:
-boot.classpath.j2se1.7=c:/Program Files/Java/jre7/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
diff --git a/build.xml b/build.xml
index b1adffc..dfab241 100644
--- a/build.xml
+++ b/build.xml
@@ -43,9 +43,6 @@
   <property name="server.ivy.repo.root" value="${basedir}/build/dummy-server-ivy-repo" />
   
   <property file="build.properties"/>
-  <condition property="has.explicit.boot.classpath.j2se1.7">
-    <isset property="boot.classpath.j2se1.7"/>
-  </condition>
   <condition property="has.explicit.boot.classpath.j2se1.8">
     <isset property="boot.classpath.j2se1.8"/>
   </condition>
@@ -58,14 +55,9 @@
 
   <!-- When boot.classpath.j2se* is missing, these will be the defaults: -->
   <!-- Note: Target "dist" doesn't allow using these. -->
-  <property name="boot.classpath.j2se1.7" 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.7}"
-    classname="java.nio.file.Path" ignoresystemclasses="true" 
-    property="boot.classpath.j2se1.7.correct"
-  />
   <available classpath="${boot.classpath.j2se1.8}"
     classname="java.time.Instant" ignoresystemclasses="true" 
     property="boot.classpath.j2se1.8.correct"
@@ -202,12 +194,6 @@
   </target>
    
   <target name="compile" depends="javacc">
-    <fail unless="boot.classpath.j2se1.7.correct"><!--
-      -->The "boot.classpath.j2se1.7" property value (${boot.classpath.j2se1.7}) <!--
-      -->seems to be an incorrect boot classpath. Please fix it in <!--
-      -->the &lt;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 <!--
@@ -216,7 +202,6 @@
     --></fail>
     <echo level="info"><!--
       -->Using boot classpaths: <!--
-      -->Java 7: ${boot.classpath.j2se1.7};<!--
       -->Java 8: ${boot.classpath.j2se1.8}<!--
     --></echo>
 
@@ -244,10 +229,10 @@
     <!-- Note: the "build.base" conf doesn't include optional FreeMarker dependencies. -->
     <ivy:cachepath conf="build.base" pathid="ivy.dep" />
     <javac destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       excludes="
         freemarker/core/_Java?*Impl.java,
         freemarker/ext/jsp/**,
@@ -264,15 +249,6 @@
       </src>
     </javac>
 
-    <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"
       classpathref="ivy.dep"
@@ -281,10 +257,10 @@
 
     <ivy:cachepath conf="build.jsp2.0" pathid="ivy.dep.jsp2.0" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep.jsp2.0"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       includes="
         freemarker/ext/jsp/**,
         freemarker/ext/servlet/**,
@@ -299,10 +275,10 @@
     
     <ivy:cachepath conf="build.jsp2.1" pathid="ivy.dep.jsp2.1" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep.jsp2.1"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       includes="
         freemarker/ext/jsp/_FreeMarkerPageContext21.java,
         freemarker/ext/jsp/FreeMarkerJspFactory21.java,
@@ -311,10 +287,10 @@
 
     <ivy:cachepath conf="build.jython2.0" pathid="ivy.dep.jython2.0" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep.jython2.0"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       includes="
         freemarker/ext/ant/**,
         freemarker/template/utility/JythonRuntime.java,
@@ -326,20 +302,20 @@
     
     <ivy:cachepath conf="build.jython2.2" pathid="ivy.dep.jython2.2" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep.jython2.2"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       includes="
         freemarker/ext/jython/_Jython22VersionAdapter.java"
     />
     
     <ivy:cachepath conf="build.jython2.5" pathid="ivy.dep.jython2.5" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.7" source="1.7" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep.jython2.5"
-      bootclasspath="${boot.classpath.j2se1.7}"
+      bootclasspath="${boot.classpath.j2se1.8}"
       includes="
         freemarker/ext/jython/_Jython25VersionAdapter.java"
     />
diff --git a/osgi.bnd b/osgi.bnd
index 08bac25..906f74d 100644
--- a/osgi.bnd
+++ b/osgi.bnd
@@ -49,10 +49,10 @@ Import-Package: !freemarker.*, *;resolution:="optional"
 # This is needed for "a.class.from.another.Bundle"?new() to work.
 DynamicImport-Package: *
 
-# The required minimum is 1.5, but we utilize versions up to 1.8 if available.
-# See also: http://wiki.eclipse.org/Execution_Environments, "Compiling
-# against more than is required"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.8, JavaSE-1.7, JavaSE-1.6, J2SE-1.5
+# List whole version range between minimum up to where we use new features
+# if available. See also: http://wiki.eclipse.org/Execution_Environments,
+# "Compiling against more than is required"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 
 # Non-OSGi meta:
 Main-Class: freemarker.core.CommandLine
diff --git a/src/main/java/freemarker/core/_Java8Impl.java b/src/main/java/freemarker/core/_Java8Impl.java
deleted file mode 100644
index a25e0f3..0000000
--- a/src/main/java/freemarker/core/_Java8Impl.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-// 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
-    }    
-
-    @Override
-    public boolean isDefaultMethod(Method method) {
-        return method.isDefault();
-    }
-
-}
diff --git a/src/main/java/freemarker/core/_JavaVersions.java b/src/main/java/freemarker/core/_JavaVersions.java
deleted file mode 100644
index 3f07673..0000000
--- a/src/main/java/freemarker/core/_JavaVersions.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 freemarker.log.Logger;
-import freemarker.template.Version;
-import freemarker.template.utility.SecurityUtilities;
-
-/**
- * Used internally only, might changes without notice!
- */
-public final class _JavaVersions {
-    
-    private _JavaVersions() {
-        // Not meant to be instantiated
-    }
-
-    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;
-    }
-    
-}
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index e0c5135..8b5f276 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -48,7 +48,6 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import freemarker.core.BugException;
-import freemarker.core._JavaVersions;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
 import freemarker.ext.util.ModelCache;
@@ -413,7 +412,7 @@ class ClassIntrospector {
         List<PropertyDescriptor> introspectorPDs = introspectorPDsArray != null ? Arrays.asList(introspectorPDsArray)
                 : Collections.<PropertyDescriptor>emptyList();
         
-        if (!treatDefaultMethodsAsBeanMembers || _JavaVersions.JAVA_8 == null) {
+        if (!treatDefaultMethodsAsBeanMembers) {
             // java.beans.Introspector was good enough then.
             return introspectorPDs;
         }
@@ -434,7 +433,7 @@ class ClassIntrospector {
         // (Note that java.beans.Introspector discovers non-accessible public methods, and to emulate that behavior
         // here, we don't utilize the accessibleMethods Map, which we might already have at this point.)
         for (Method method : clazz.getMethods()) {
-            if (_JavaVersions.JAVA_8.isDefaultMethod(method) && method.getReturnType() != void.class
+            if (method.isDefault() && method.getReturnType() != void.class
                     && !method.isBridge()) {
                 Class<?>[] paramTypes = method.getParameterTypes();
                 if (paramTypes.length == 0
@@ -607,14 +606,14 @@ class ClassIntrospector {
         List<MethodDescriptor> introspectionMDs = introspectorMDArray != null && introspectorMDArray.length != 0
                 ? Arrays.asList(introspectorMDArray) : Collections.<MethodDescriptor>emptyList();
 
-        if (!treatDefaultMethodsAsBeanMembers || _JavaVersions.JAVA_8 == null) {
+        if (!treatDefaultMethodsAsBeanMembers) {
             // java.beans.Introspector was good enough then.
             return introspectionMDs;
         }
 
         Map<String, List<Method>> defaultMethodsToAddByName = null;
         for (Method method : clazz.getMethods()) {
-            if (_JavaVersions.JAVA_8.isDefaultMethod(method) && !method.isBridge()) {
+            if (method.isDefault() && !method.isBridge()) {
                 if (defaultMethodsToAddByName == null) {
                     defaultMethodsToAddByName = new HashMap<>();
                 }
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperMiscTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperMiscTest.java
index c3ff772..ac7a7b7 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperMiscTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperMiscTest.java
@@ -29,7 +29,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-import freemarker.core._JavaVersions;
 import freemarker.template.Configuration;
 import freemarker.template.TemplateBooleanModel;
 import freemarker.template.TemplateHashModel;
@@ -101,7 +100,6 @@ public class BeansWrapperMiscTest {
 
     @Test
     public void java8InaccessibleIndexedAccessibleNonIndexedReadMethodTest() throws TemplateModelException {
-        assertTrue("This test case must be ran on Java 8 or later", _JavaVersions.JAVA_8 != null);
         assertFalse(Modifier.isPublic(BeanWithInaccessibleIndexedProperty.class.getModifiers()));
         
         for (Version ici : new Version[] { Configuration.VERSION_2_3_26, Configuration.VERSION_2_3_27 }) {