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 2017/10/06 19:34:55 UTC
incubator-freemarker git commit: Added workaround against
IllegalStateException: zip file closed issues (caused by bugs outside of
FreeMarker) when loading resources included in the FreeMarker jar (see
freemarker.template.utility.ClassUtil.getReasourceAs
Repository: incubator-freemarker
Updated Branches:
refs/heads/2.3-gae 5cee74f81 -> bd7498e8d
Added workaround against IllegalStateException: zip file closed issues (caused by bugs outside of FreeMarker) when loading resources included in the FreeMarker jar (see freemarker.template.utility.ClassUtil.getReasourceAsStream). Related to https://github.com/apache/incubator-freemarker/pull/37.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/bd7498e8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/bd7498e8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/bd7498e8
Branch: refs/heads/2.3-gae
Commit: bd7498e8d7e724c7bbc1f769f001b3f7df56debf
Parents: 5cee74f
Author: ddekany <dd...@apache.org>
Authored: Fri Oct 6 21:34:48 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Fri Oct 6 21:34:48 2017 +0200
----------------------------------------------------------------------
.../freemarker/ext/beans/UnsafeMethods.java | 6 +-
.../java/freemarker/ext/jsp/TaglibFactory.java | 15 +----
.../java/freemarker/template/Configuration.java | 68 ++++++++++----------
.../freemarker/template/utility/ClassUtil.java | 48 ++++++++++++++
src/manual/en_US/book.xml | 8 +++
5 files changed, 92 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/bd7498e8/src/main/java/freemarker/ext/beans/UnsafeMethods.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/UnsafeMethods.java b/src/main/java/freemarker/ext/beans/UnsafeMethods.java
index ed6d248..f590085 100644
--- a/src/main/java/freemarker/ext/beans/UnsafeMethods.java
+++ b/src/main/java/freemarker/ext/beans/UnsafeMethods.java
@@ -44,13 +44,9 @@ class UnsafeMethods {
private static final Set createUnsafeMethodsSet() {
Properties props = new Properties();
- InputStream in = BeansWrapper.class.getResourceAsStream("unsafeMethods.properties");
- if (in == null) {
- throw new IllegalStateException("Class loader resource not found: "
- + BeansWrapper.class.getPackage().getName() + UNSAFE_METHODS_PROPERTIES);
- }
String methodSpec = null;
try {
+ InputStream in = ClassUtil.getReasourceAsStream(BeansWrapper.class, UNSAFE_METHODS_PROPERTIES);
try {
props.load(in);
} finally {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/bd7498e8/src/main/java/freemarker/ext/jsp/TaglibFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/TaglibFactory.java b/src/main/java/freemarker/ext/jsp/TaglibFactory.java
index fbb11a4..0dc07b1 100644
--- a/src/main/java/freemarker/ext/jsp/TaglibFactory.java
+++ b/src/main/java/freemarker/ext/jsp/TaglibFactory.java
@@ -1257,17 +1257,10 @@ public class TaglibFactory implements TemplateHashModel {
public InputStream getInputStream() throws IOException {
ClassLoader tccl = tryGetThreadContextClassLoader();
if (tccl != null) {
- final InputStream in = getClass().getResourceAsStream(resourcePath);
- if (in != null) {
- return in;
- }
+ return ClassUtil.getReasourceAsStream(getClass(), resourcePath);
}
- final InputStream in = getClass().getResourceAsStream(resourcePath);
- if (in == null) {
- throw newResourceNotFoundException();
- }
- return in;
+ return ClassUtil.getReasourceAsStream(getClass(), resourcePath);
}
public String getXmlSystemId() throws IOException {
@@ -1282,10 +1275,6 @@ public class TaglibFactory implements TemplateHashModel {
final URL url = getClass().getResource(resourcePath);
return url == null ? null : url.toExternalForm();
}
-
- private IOException newResourceNotFoundException() {
- return new IOException("Resource not found: classpath:" + resourcePath);
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/bd7498e8/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index 95d4172..53358b1 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -151,7 +151,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
private static final Logger CACHE_LOG = Logger.getLogger("freemarker.cache");
- private static final String VERSION_PROPERTIES_PATH = "freemarker/version.properties";
+ private static final String VERSION_PROPERTIES_PATH = "/freemarker/version.properties";
/** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23 */
public static final String DEFAULT_ENCODING_KEY_SNAKE_CASE = "default_encoding";
@@ -436,36 +436,31 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
static {
try {
Properties vp = new Properties();
- InputStream ins = Configuration.class.getClassLoader()
- .getResourceAsStream(VERSION_PROPERTIES_PATH);
- if (ins == null) {
- throw new RuntimeException("Version file is missing.");
- } else {
- try {
- vp.load(ins);
- } finally {
- ins.close();
+ InputStream ins = ClassUtil.getReasourceAsStream(Configuration.class, VERSION_PROPERTIES_PATH);
+ try {
+ vp.load(ins);
+ } finally {
+ ins.close();
+ }
+
+ String versionString = getRequiredVersionProperty(vp, "version");
+
+ Date buildDate;
+ {
+ String buildDateStr = getRequiredVersionProperty(vp, "buildTimestamp");
+ if (buildDateStr.endsWith("Z")) {
+ buildDateStr = buildDateStr.substring(0, buildDateStr.length() - 1) + "+0000";
}
-
- String versionString = getRequiredVersionProperty(vp, "version");
-
- Date buildDate;
- {
- String buildDateStr = getRequiredVersionProperty(vp, "buildTimestamp");
- if (buildDateStr.endsWith("Z")) {
- buildDateStr = buildDateStr.substring(0, buildDateStr.length() - 1) + "+0000";
- }
- try {
- buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US).parse(buildDateStr);
- } catch (java.text.ParseException e) {
- buildDate = null;
- }
+ try {
+ buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US).parse(buildDateStr);
+ } catch (java.text.ParseException e) {
+ buildDate = null;
}
-
- final Boolean gaeCompliant = Boolean.valueOf(getRequiredVersionProperty(vp, "isGAECompliant"));
-
- VERSION = new Version(versionString, gaeCompliant, buildDate);
}
+
+ final Boolean gaeCompliant = Boolean.valueOf(getRequiredVersionProperty(vp, "isGAECompliant"));
+
+ VERSION = new Version(versionString, gaeCompliant, buildDate);
} catch (IOException e) {
throw new RuntimeException("Failed to load and parse " + VERSION_PROPERTIES_PATH, e);
}
@@ -537,6 +532,8 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
private ConcurrentMap localeToCharsetMap = new ConcurrentHashMap();
/**
+ * Same as {@link #Configuration(Version) Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS)}.
+ *
* @deprecated Use {@link #Configuration(Version)} instead. Note that the version can be still modified later with
* {@link Configuration#setIncompatibleImprovements(Version)} (or
* {@link Configuration#setSettings(Properties)}).
@@ -555,11 +552,11 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
*
* <p>This setting value is the FreeMarker version number where the not 100% backward compatible bug fixes and
* improvements that you want to enable were already implemented. In new projects you should set this to the
- * FreeMarker version that you are actually using. In older projects it's also usually better to keep this high,
- * however you better check the changes activated (find them below), at least if not only the 3rd version number
- * (the micro version) of {@code incompatibleImprovements} is increased. Generally, as far as you only increase the
- * last version number of this setting, the changes are always low risk. The default value is 2.3.0 to maximize
- * backward compatibility, but that value isn't recommended.
+ * version of FreeMarker that you start the development with. In older projects it's also usually better to keep
+ * this high, however you should check the changes activated (find them below), especially if not only the 3rd
+ * version number (the micro version) of {@code incompatibleImprovements} is increased. Generally, as far as you
+ * only increase the last version number of this setting, the changes are low risk. The default value is 2.3.0 to
+ * maximize backward compatibility, but that value isn't recommended.
*
* <p>Bugfixes and improvements that are fully backward compatible, also those that are important security fixes,
* are enabled regardless of the incompatible improvements setting.
@@ -576,8 +573,9 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
* <p>Currently the effects of this setting are:
* <ul>
* <li><p>
- * 2.3.0: This is the lowest supported value, the version used in older projects. This is the default in the
- * FreeMarker 2.3.x series.
+ * 2.3.0: This is the lowest supported value, the version used in very old projects. This is the default in the
+ * FreeMarker 2.3.x series (the one used by the deprecated {@link #Configuration()} constructor) for maximum
+ * backward compatibility.
* </li>
* <li><p>
* 2.3.19 (or higher): Bug fix: Wrong {@code #} tags were printed as static text instead of
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/bd7498e8/src/main/java/freemarker/template/utility/ClassUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/utility/ClassUtil.java b/src/main/java/freemarker/template/utility/ClassUtil.java
index 0aa40cb..7d97839 100644
--- a/src/main/java/freemarker/template/utility/ClassUtil.java
+++ b/src/main/java/freemarker/template/utility/ClassUtil.java
@@ -19,6 +19,9 @@
package freemarker.template.utility;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
import java.util.HashSet;
import java.util.Set;
@@ -379,4 +382,49 @@ public class ClassUtil {
|| type.isPrimitive() && type != Boolean.TYPE && type != Character.TYPE && type != Void.TYPE;
}
+ /**
+ * Very similar to {@link Class#getResourceAsStream(String)}, but throws {@link IOException} instead of returning
+ * {@code null}, and attempts to work around "IllegalStateException: zip file closed" issues (caused by bugs
+ * outside of FreeMarker).
+ *
+ * @return Never {@code null}
+ * @throws IOException If the resource wasn't found, or other {@link IOException} occurs.
+ */
+ public static InputStream getReasourceAsStream(Class<?> baseClass, String resource) throws IOException {
+ InputStream ins;
+ try {
+ ins = baseClass.getResourceAsStream(resource);
+ } catch (IllegalStateException e) {
+ // Workaround for "IllegalStateException: zip file closed". This happens due to bugs outside of FreeMarker
+ // (sometimes caused by the caching of jar URL connection streams), but we try to work it around anyway.
+ URL url = baseClass.getResource(resource);
+ ins = url != null ? url.openStream() : null;
+ }
+ if (ins == null) {
+ throw new IOException("Class-loader resource not found (shown quoted): \""
+ + StringUtil.jQuote(resource) + "\". The base class was " + baseClass.getName() + ".");
+ }
+ return ins;
+ }
+
+ /**
+ * Same as {@link #getReasourceAsStream(Class, String)}, but uses a {@link ClassLoader} directly instead of a
+ * {@link Class}.
+ */
+ public static InputStream getReasourceAsStream(ClassLoader classLoader, String resource)
+ throws IOException {
+ InputStream ins;
+ try {
+ ins = classLoader.getResourceAsStream(resource);
+ } catch (IllegalStateException e) {
+ URL url = classLoader.getResource(resource);
+ ins = url != null ? url.openStream() : null;
+ }
+ if (ins == null) {
+ throw new IOException("Class-loader resource not found (shown quoted): \""
+ + StringUtil.jQuote(resource) + "\". The base ClassLoader was: " + classLoader);
+ }
+ return ins;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/bd7498e8/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 4573010..2068fe3 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -27349,6 +27349,14 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
</itemizedlist>
</listitem>
+
+ <listitem>
+ <para>Added workaround against <quote>IllegalStateException: zip
+ file closed</quote> issues (caused by bugs outside of
+ FreeMarker) when loading resources included in the FreeMarker
+ jar (see
+ <literal>freemarker.template.utility.ClassUtil.getReasourceAsStream</literal>).</para>
+ </listitem>
</itemizedlist>
</section>
</section>