This is an automated email from the ASF dual-hosted git repository. yasserzamani pushed a commit to branch struts-2-5-x in repository https://gitbox.apache.org/repos/asf/struts.git
commit 75dc4c00d20a1bde86897dc73ff5098b91eaf0f0 Author: Yasser Zamani <yasserzam...@apache.org> AuthorDate: Sun Nov 11 14:31:35 2018 +0330 pass all current tests with java 9 See also WW-4845 (cherry picked from commit a5d888a) --- .travis.yml | 1 + .../opensymphony/xwork2/util/ClassPathFinder.java | 33 ++++----- .../com/opensymphony/xwork2/ognl/OgnlUtilTest.java | 15 ++++- .../test/java/org/apache/struts2/TestUtils.java | 17 +++++ .../struts2/jasper/JspCompilationContext.java | 4 +- .../struts2/jasper/compiler/JspRuntimeContext.java | 78 +++++++++++++--------- .../struts2/jasper/compiler/TagFileProcessor.java | 3 +- .../struts2/jasper/compiler/TldLocationsCache.java | 44 ++++++------ 8 files changed, 117 insertions(+), 78 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14daf85..8d98574 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ sudo: false jdk: - openjdk7 - oraclejdk8 + - oraclejdk9 install: true script: mvn test -DskipAssembly diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java b/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java index 5188149..5838abd 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ClassPathFinder.java @@ -27,6 +27,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Collections; import java.util.HashMap; import java.util.Vector; import java.util.zip.ZipEntry; @@ -77,11 +78,7 @@ public class ClassPathFinder { */ public Vector<String> findMatches() { Vector<String> matches = new Vector<>(); - URLClassLoader cl = getURLClassLoader(); - if (cl == null ) { - throw new XWorkException("unable to attain an URLClassLoader") ; - } - URL[] parentUrls = cl.getURLs(); + URL[] parentUrls = getClassLoaderURLs(); compiledPattern = patternMatcher.compilePattern(pattern); for (URL url : parentUrls) { if (!"file".equals(url.getProtocol())) { @@ -173,20 +170,24 @@ public class ClassPathFinder { this.patternMatcher = patternMatcher; } - private URLClassLoader getURLClassLoader() { - URLClassLoader ucl = null; + private URL[] getClassLoaderURLs() { + URL[] urls; ClassLoader loader = Thread.currentThread().getContextClassLoader(); - - if(! (loader instanceof URLClassLoader)) { + + if (!(loader instanceof URLClassLoader)) { loader = ClassPathFinder.class.getClassLoader(); - if (loader instanceof URLClassLoader) { - ucl = (URLClassLoader) loader ; - } } - else { - ucl = (URLClassLoader) loader; + + if (loader instanceof URLClassLoader) { + urls = ((URLClassLoader) loader).getURLs(); + } else { //jdk9 or later + try { + urls = Collections.list(loader.getResources("")).toArray(new URL[0]); + } catch (IOException e) { + throw new XWorkException("unable to get ClassLoader URLs", e); + } } - - return ucl ; + + return urls; } } diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index ca11433..d6372fd 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -27,6 +27,7 @@ import com.opensymphony.xwork2.test.User; import com.opensymphony.xwork2.util.*; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import ognl.*; +import org.apache.struts2.TestUtils; import java.lang.reflect.Method; import java.util.*; @@ -374,8 +375,18 @@ public class OgnlUtilTest extends XWorkTestCase { assertEquals(cal.getTime(), foo.getBirthday()); //UK style test - props.put("event", "18/10/2006 14:23:45"); - props.put("meeting", "09/09/2006 14:30"); + if (TestUtils.isJdk9OrLater()) { + /* In JDK 9 and later, the default locale data uses data derived from the + Unicode Consortium's Common Locale Data Repository (CLDR). The short date-time format is ‹{1}, {0}› in the + CLDR locale, as opposed to {1} {0} in the JRE locale data. + Please refer : http://www.oracle.com/technetwork/java/javase/9-relnote-issues-3704069.html#JDK-8008577 */ + props.put("event", "18/10/2006, 14:23:45"); + props.put("meeting", "09/09/2006, 14:30"); + } + else { + props.put("event", "18/10/2006 14:23:45"); + props.put("meeting", "09/09/2006 14:30"); + } context.put(ActionContext.LOCALE, Locale.UK); ognlUtil.setProperties(props, foo, context); diff --git a/core/src/test/java/org/apache/struts2/TestUtils.java b/core/src/test/java/org/apache/struts2/TestUtils.java index 88789e1..111cd89 100644 --- a/core/src/test/java/org/apache/struts2/TestUtils.java +++ b/core/src/test/java/org/apache/struts2/TestUtils.java @@ -20,6 +20,7 @@ package org.apache.struts2; import java.io.InputStream; import java.net.URL; +import java.net.URLClassLoader; import java.util.StringTokenizer; /** @@ -90,4 +91,20 @@ public class TestUtils { return buffer.toString(); } + + public static boolean isJdk9OrLater() { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + + if(loader instanceof URLClassLoader) { + return false; + } + + loader = TestUtils.class.getClassLoader(); + + if(loader instanceof URLClassLoader) { + return false; + } + + return true; + } } diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspCompilationContext.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspCompilationContext.java index a8fbb60..b0bb32c 100644 --- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspCompilationContext.java +++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspCompilationContext.java @@ -80,7 +80,7 @@ public class JspCompilationContext { protected String baseURI; protected String outputDir; protected ServletContext context; - protected URLClassLoader loader; + protected ClassLoader loader; protected JspRuntimeContext rctxt; @@ -177,7 +177,7 @@ public class JspCompilationContext { return rctxt.getParentClassLoader(); } - public void setClassLoader(URLClassLoader loader) { + public void setClassLoader(ClassLoader loader) { this.loader = loader; } diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspRuntimeContext.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspRuntimeContext.java index b2316b5..e9698e2 100644 --- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspRuntimeContext.java +++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspRuntimeContext.java @@ -33,12 +33,14 @@ import javax.servlet.jsp.JspFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.FilePermission; +import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Policy; import java.security.cert.Certificate; +import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -121,11 +123,9 @@ public final class JspRuntimeContext { this.options = options; // Get the parent class loader - parentClassLoader = - (URLClassLoader) Thread.currentThread().getContextClassLoader(); + parentClassLoader = Thread.currentThread().getContextClassLoader(); if (parentClassLoader == null) { - parentClassLoader = - (URLClassLoader) this.getClass().getClassLoader(); + parentClassLoader = this.getClass().getClassLoader(); } if (log.isDebugEnabled()) { @@ -138,7 +138,11 @@ public final class JspRuntimeContext { } } - initClassPath(); + try { + initClassPath(); + } catch (IOException e) { + context.log("ClassPath Init for context failed", e); + } if (context instanceof JspCServletContext) { return; @@ -165,7 +169,7 @@ public final class JspRuntimeContext { */ private ServletContext context; private Options options; - private URLClassLoader parentClassLoader; + private ClassLoader parentClassLoader; private PermissionCollection permissionCollection; private CodeSource codeSource; private String classpath; @@ -233,7 +237,7 @@ public final class JspRuntimeContext { * * @return URLClassLoader parent */ - public URLClassLoader getParentClassLoader() { + public ClassLoader getParentClassLoader() { return parentClassLoader; } @@ -333,9 +337,14 @@ public final class JspRuntimeContext { /** * Method used to initialize classpath for compiles. */ - private void initClassPath() { + private void initClassPath() throws IOException { - URL[] urls = parentClassLoader.getURLs(); + URL[] urls; + if (parentClassLoader instanceof URLClassLoader) { + urls = ((URLClassLoader) parentClassLoader).getURLs(); + } else { //jdk9 or later + urls = Collections.list(parentClassLoader.getResources("")).toArray(new URL[0]); + } StringBuffer cpath = new StringBuffer(); String sep = System.getProperty("path.separator"); @@ -418,34 +427,37 @@ public final class JspRuntimeContext { permissionCollection.add(new RuntimePermission( "accessClassInPackage.org.apache.struts2.jasper.runtime")); + URL[] urls; if (parentClassLoader instanceof URLClassLoader) { - URL[] urls = parentClassLoader.getURLs(); - String jarUrl = null; - String jndiUrl = null; - for (int i = 0; i < urls.length; i++) { - if (jndiUrl == null - && urls[i].toString().startsWith("jndi:")) { - jndiUrl = urls[i].toString() + "-"; - } - if (jarUrl == null - && urls[i].toString().startsWith("jar:jndi:") - ) { - jarUrl = urls[i].toString(); - jarUrl = jarUrl.substring(0, jarUrl.length() - 2); - jarUrl = jarUrl.substring(0, - jarUrl.lastIndexOf('/')) + "/-"; - } + urls = ((URLClassLoader) parentClassLoader).getURLs(); + } else { //jdk9 or later + urls = Collections.list(parentClassLoader.getResources("")).toArray(new URL[0]); + } + String jarUrl = null; + String jndiUrl = null; + for (URL url1 : urls) { + if (jndiUrl == null + && url1.toString().startsWith("jndi:")) { + jndiUrl = url1.toString() + "-"; } - if (jarUrl != null) { - permissionCollection.add( - new FilePermission(jarUrl, "read")); - permissionCollection.add( - new FilePermission(jarUrl.substring(4), "read")); + if (jarUrl == null + && url1.toString().startsWith("jar:jndi:") + ) { + jarUrl = url1.toString(); + jarUrl = jarUrl.substring(0, jarUrl.length() - 2); + jarUrl = jarUrl.substring(0, + jarUrl.lastIndexOf('/')) + "/-"; } - if (jndiUrl != null) - permissionCollection.add( - new FilePermission(jndiUrl, "read")); } + if (jarUrl != null) { + permissionCollection.add( + new FilePermission(jarUrl, "read")); + permissionCollection.add( + new FilePermission(jarUrl.substring(4), "read")); + } + if (jndiUrl != null) + permissionCollection.add( + new FilePermission(jndiUrl, "read")); } catch (Exception e) { context.log("Security Init for context failed", e); } diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TagFileProcessor.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TagFileProcessor.java index 5f3d13a..bbf2417 100644 --- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TagFileProcessor.java +++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TagFileProcessor.java @@ -594,8 +594,7 @@ class TagFileProcessor { rctxt.addWrapper(tagFileJarPath + tagFilePath, wrapper); // Use same classloader and classpath for compiling tag files - wrapper.getJspEngineContext().setClassLoader( - (URLClassLoader) ctxt.getClassLoader()); + wrapper.getJspEngineContext().setClassLoader(ctxt.getClassLoader()); wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath()); } else { // Make sure that JspCompilationContext gets the latest TagInfo diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TldLocationsCache.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TldLocationsCache.java index 0bac6fa..a8a26be 100644 --- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TldLocationsCache.java +++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/TldLocationsCache.java @@ -25,12 +25,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.StringTokenizer; +import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.xml.sax.InputSource; @@ -508,24 +503,27 @@ public class TldLocationsCache { ClassLoader loader = webappLoader; while (loader != null) { + URL[] urls; if (loader instanceof URLClassLoader) { - URL[] urls = ((URLClassLoader) loader).getURLs(); - for (int i=0; i<urls.length; i++) { - URLConnection conn = urls[i].openConnection(); - if (conn instanceof JarURLConnection) { - if (needScanJar(loader, webappLoader, - ((JarURLConnection) conn).getJarFile().getName())) { - scanJar((JarURLConnection) conn, true); - } - } else { - String urlStr = urls[i].toString(); - if (urlStr.startsWith(FILE_PROTOCOL) - && urlStr.endsWith(JAR_FILE_SUFFIX) - && needScanJar(loader, webappLoader, urlStr)) { - URL jarURL = new URL("jar:" + urlStr + "!/"); - scanJar((JarURLConnection) jarURL.openConnection(), - true); - } + urls = ((URLClassLoader) loader).getURLs(); + } else { //jdk9 or later + urls = Collections.list(loader.getResources("")).toArray(new URL[0]); + } + for (URL url : urls) { + URLConnection conn = url.openConnection(); + if (conn instanceof JarURLConnection) { + if (needScanJar(loader, webappLoader, + ((JarURLConnection) conn).getJarFile().getName())) { + scanJar((JarURLConnection) conn, true); + } + } else { + String urlStr = url.toString(); + if (urlStr.startsWith(FILE_PROTOCOL) + && urlStr.endsWith(JAR_FILE_SUFFIX) + && needScanJar(loader, webappLoader, urlStr)) { + URL jarURL = new URL("jar:" + urlStr + "!/"); + scanJar((JarURLConnection) jarURL.openConnection(), + true); } } }