From 12327b8876b5a7d5935a6d0e09ce5013bffb165a Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 15 Nov 2017 10:33:51 +0100 Subject: [PATCH 1/2] Issue #1933 Signed-off-by: Jan Bartel --- .../annotations/AnnotationConfiguration.java | 3 +- .../org/eclipse/jetty/util/JavaVersion.java | 3 + jetty-webapp/pom.xml | 19 ++ .../jetty/webapp/WebInfConfiguration.java | 237 +++++++++++++++--- .../jetty/webapp/WebInfConfigurationTest.java | 113 +++++++++ .../src/test/resources/mods/com-acme-janb.jar | Bin 0 -> 1772 bytes .../src/test/resources/mods/foo-bar-janb.jar | Bin 0 -> 1246 bytes 7 files changed, 339 insertions(+), 36 deletions(-) create mode 100644 jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java create mode 100644 jetty-webapp/src/test/resources/mods/com-acme-janb.jar create mode 100644 jetty-webapp/src/test/resources/mods/foo-bar-janb.jar diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index cc453c4b46c..6b8ace0cf5a 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -45,6 +45,7 @@ import javax.servlet.annotation.HandlesTypes; import org.eclipse.jetty.annotations.AnnotationParser.Handler; import org.eclipse.jetty.plus.annotation.ContainerInitializer; +import org.eclipse.jetty.util.JavaVersion; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; @@ -72,7 +73,7 @@ public class AnnotationConfiguration extends AbstractConfiguration public static final String CONTAINER_INITIALIZER_STARTER = "org.eclipse.jetty.containerInitializerStarter"; public static final String MULTI_THREADED = "org.eclipse.jetty.annotations.multiThreaded"; public static final String MAX_SCAN_WAIT = "org.eclipse.jetty.annotations.maxWait"; - public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform"; + public static final String JAVA_TARGET_PLATFORM = JavaVersion.JAVA_TARGET_PLATFORM; public static final int DEFAULT_MAX_SCAN_WAIT = 60; /* time in sec */ public static final boolean DEFAULT_MULTI_THREADED = true; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java index 6dd630251ec..0df8f900fde 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java @@ -27,6 +27,9 @@ import java.util.regex.Pattern; */ public class JavaVersion { + + public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform"; + // Copy of version in jetty-start private static final Pattern PRE_JDK9 = Pattern.compile("1\\.(\\d)(\\.(\\d+)(_(\\d+))?)?(-.+)?"); diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index db037264636..48b44c577ca 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -38,6 +38,7 @@ org.apache.maven.plugins maven-surefire-plugin + false org.eclipse.jetty.webapp.WebAppClassLoaderUrlStreamTest @@ -70,4 +71,22 @@ true + + + jdk9 + + [1.9,) + + + + + maven-surefire-plugin + + @{argLine} --module-path src/test/resources/mods + + + + + + diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index 05238c03513..5a9f7895ac6 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -24,6 +24,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -36,6 +38,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.JavaVersion; import org.eclipse.jetty.util.PatternMatcher; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; @@ -61,6 +64,84 @@ public class WebInfConfiguration extends AbstractConfiguration protected Resource _preUnpackBaseResource; + /** + * ContainerPathNameMatcher + * + * Matches names of jars on the container classpath + * against a pattern. If no pattern is specified, no + * jars match. + */ + public class ContainerPathNameMatcher extends PatternMatcher + { + protected final WebAppContext _context; + protected final Pattern _pattern; + + public ContainerPathNameMatcher(WebAppContext context, Pattern pattern) + { + if (context == null) + throw new IllegalArgumentException("Context null"); + _context = context; + _pattern = pattern; + } + + + public void match (List uris) + throws Exception + { + if (uris == null) + return; + match(_pattern, uris.toArray(new URI[uris.size()]), false); + } + + + + /** + * @see org.eclipse.jetty.util.PatternMatcher#matched(java.net.URI) + */ + @Override + public void matched(URI uri) throws Exception + { + _context.getMetaData().addContainerResource(Resource.newResource(uri)); + } + } + + + /** + * WebAppPathNameMatcher + * + * Matches names of jars or dirs on the webapp classpath + * against a pattern. If there is no pattern, all jars or dirs + * will match. + */ + public class WebAppPathNameMatcher extends PatternMatcher + { + protected final WebAppContext _context; + protected final Pattern _pattern; + + public WebAppPathNameMatcher (WebAppContext context, Pattern pattern) + { + if (context == null) + throw new IllegalArgumentException("Context null"); + _context=context; + _pattern=pattern; + } + + public void match (List uris) + throws Exception + { + match(_pattern, uris.toArray(new URI[uris.size()]), true); + } + + /** + * @see org.eclipse.jetty.util.PatternMatcher#matched(java.net.URI) + */ + @Override + public void matched(URI uri) throws Exception + { + _context.getMetaData().addWebInfJar(Resource.newResource(uri)); + } + + } @Override @@ -72,79 +153,165 @@ public class WebInfConfiguration extends AbstractConfiguration //Extract webapp if necessary unpack (context); + findAndFilterContainerPaths(context); - //Apply an initial ordering to the jars which governs which will be scanned for META-INF - //info and annotations. The ordering is based on inclusion patterns. - String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN); - Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp)); - tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN); + findAndFilterWebAppPaths(context); + + //No pattern to appy to classes, just add to metadata + context.getMetaData().setWebInfClassesDirs(findClassDirs(context)); + } + + + + /** + * Find jars and directories that are on the container's classpath + * and apply an optional filter. The filter is a pattern applied to the + * full jar or directory names. If there is no pattern, then no jar + * or dir is considered to match. + * + * Those jars that do match will be later examined for META-INF + * information and annotations. + * + * To find them, examine the classloaders in the hierarchy above the + * webapp classloader that are URLClassLoaders. For jdk-9 we also + * look at the java.class.path, and the jdk.module.path. + * + * @param context the WebAppContext being deployed + * @throws Exception + */ + public void findAndFilterContainerPaths (final WebAppContext context) + throws Exception + { + //assume the target jvm is the same as that running + int targetPlatform = JavaVersion.VERSION.getPlatform(); + //allow user to specify target jvm different to current runtime + Object target = context.getAttribute(JavaVersion.JAVA_TARGET_PLATFORM); + if (target!=null) + targetPlatform = Integer.valueOf(target.toString()).intValue(); + + //Apply an initial name filter to the jars to select which will be eventually + //scanned for META-INF info and annotations. The filter is based on inclusion patterns. + String tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN); Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp)); - - //Apply ordering to container jars - if no pattern is specified, we won't - //match any of the container jars - PatternMatcher containerJarNameMatcher = new PatternMatcher () - { - public void matched(URI uri) throws Exception - { - context.getMetaData().addContainerResource(Resource.newResource(uri)); - } - }; + ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, containerPattern); + ClassLoader loader = null; if (context.getClassLoader() != null) loader = context.getClassLoader().getParent(); + List containerUris = new ArrayList<>(); + while (loader != null && (loader instanceof URLClassLoader)) { URL[] urls = ((URLClassLoader)loader).getURLs(); if (urls != null) { - URI[] containerUris = new URI[urls.length]; - int i=0; for (URL u : urls) { try { - containerUris[i] = u.toURI(); + containerUris.add(u.toURI()); } catch (URISyntaxException e) { - containerUris[i] = new URI(u.toString().replaceAll(" ", "%20")); + containerUris.add(new URI(u.toString().replaceAll(" ", "%20"))); } - i++; } - containerJarNameMatcher.match(containerPattern, containerUris, false); } loader = loader.getParent(); } + + if (LOG.isDebugEnabled()) LOG.debug("Matching container urls {}", containerUris); + containerPathNameMatcher.match(containerUris); - //Apply ordering to WEB-INF/lib jars - PatternMatcher webInfJarNameMatcher = new PatternMatcher () + //if running on jvm 9 or above, we we won't be able to look at the application classloader + //to extract urls, so we need to examine the classpath instead. + if (JavaVersion.VERSION.getMajor() >= 9) { - @Override - public void matched(URI uri) throws Exception + tmp = System.getProperty("java.class.path"); + if (tmp != null) { - context.getMetaData().addWebInfJar(Resource.newResource(uri)); + List cpUris = new ArrayList<>(); + String[] entries = tmp.split(File.pathSeparator); + for (String entry:entries) + { + File f = new File(entry); + cpUris.add(f.toURI()); + } + if (LOG.isDebugEnabled()) LOG.debug("Matching java.class.path {}", cpUris); + containerPathNameMatcher.match(cpUris); } - }; + } + + //if we're targetting jdk 9 or above, we also need to examine the + //module path + if (targetPlatform >= 9) + { + //TODO need to consider the jdk.module.upgrade.path - how to resolve + //which modules will be actually used. If its possible, it can + //only be attempted in jetty-10 with jdk-9 specific apis. + tmp = System.getProperty("jdk.module.path"); + if (tmp != null) + { + List moduleUris = new ArrayList<>(); + String[] entries = tmp.split(File.pathSeparator); + for (String entry:entries) + { + File dir = new File(entry); + File[] files = dir.listFiles(); + if (files != null) + { + for (File f:files) + { + moduleUris.add(f.toURI()); + } + } + + } + if (LOG.isDebugEnabled()) LOG.debug("Matching jdk.module.path {}", moduleUris); + containerPathNameMatcher.match(moduleUris); + } + } + + if (LOG.isDebugEnabled()) LOG.debug("Container paths selected:{}", context.getMetaData().getContainerResources()); + } + + + /** + * Finds the jars that are either physically or virtually in + * WEB-INF/lib, and applies an optional filter to their full + * pathnames. + * + * The filter selects which jars will later be examined for META-INF + * information and annotations. If there is no pattern, then + * all jars are considered selected. + * + * @param context the WebAppContext being deployed + * @throws Exception + */ + public void findAndFilterWebAppPaths (WebAppContext context) + throws Exception + { + String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN); + Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp)); + //Apply filter to WEB-INF/lib jars + WebAppPathNameMatcher matcher = new WebAppPathNameMatcher(context, webInfPattern); + List jars = findJars(context); //Convert to uris for matching - URI[] uris = null; if (jars != null) { - uris = new URI[jars.size()]; + List uris = new ArrayList<>(); int i=0; for (Resource r: jars) { - uris[i++] = r.getURI(); + uris.add(r.getURI()); } + matcher.match(uris); } - webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match - - //No pattern to appy to classes, just add to metadata - context.getMetaData().setWebInfClassesDirs(findClassDirs(context)); } - + @Override public void configure(WebAppContext context) throws Exception diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java new file mode 100644 index 00000000000..ea9f6919b5d --- /dev/null +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java @@ -0,0 +1,113 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.webapp; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.eclipse.jetty.util.JavaVersion; +import org.eclipse.jetty.util.resource.Resource; +import org.junit.Assume; +import org.junit.Test; + +/** + * WebInfConfigurationTest + * + * + */ +public class WebInfConfigurationTest +{ + + /** + * Assume target < jdk9. In this case, we should be able to extract + * the urls from the application classloader, and we should not look + * at the java.class.path property. + * @throws Exception + */ + @Test + public void testFindAndFilterContainerPaths() + throws Exception + { + Assume.assumeTrue(JavaVersion.VERSION.getMajor() < 9); + WebInfConfiguration config = new WebInfConfiguration(); + WebAppContext context = new WebAppContext(); + context.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, ".*/jetty-util-[^/]*\\.jar$|.*/jetty-util/target/classes/"); + WebAppClassLoader loader = new WebAppClassLoader(context); + context.setClassLoader(loader); + config.findAndFilterContainerPaths(context); + List containerResources = context.getMetaData().getContainerResources(); + assertEquals(1, containerResources.size()); + assertTrue(containerResources.get(0).toString().contains("jetty-util")); + } + + /** + * Assume target jdk9 or above. In this case we should extract what we need + * from the java.class.path. We should also examine the module path. + * @throws Exception + */ + @Test + public void testFindAndFilterContainerPathsJDK9() + throws Exception + { + Assume.assumeTrue(JavaVersion.VERSION.getMajor() >= 9); + Assume.assumeTrue(System.getProperty("jdk.module.path") != null); + WebInfConfiguration config = new WebInfConfiguration(); + WebAppContext context = new WebAppContext(); + context.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, ".*/jetty-util-[^/]*\\.jar$|.*/jetty-util/target/classes/$|.*/foo-bar-janb.jar"); + WebAppClassLoader loader = new WebAppClassLoader(context); + context.setClassLoader(loader); + config.findAndFilterContainerPaths(context); + List containerResources = context.getMetaData().getContainerResources(); + assertEquals(2, containerResources.size()); + for (Resource r:containerResources) + { + String s = r.toString(); + assertTrue(s.endsWith("foo-bar-janb.jar") || s.contains("jetty-util")); + } + } + + + /** + * Assume runtime is jdk9 or above. Target is jdk 8. In this + * case we must extract from the java.class.path (because jdk 9 + * has no url based application classloader), but we should + * ignore the module path. + * @throws Exception + */ + @Test + public void testFindAndFilterContainerPathsTarget8() + throws Exception + { + Assume.assumeTrue(JavaVersion.VERSION.getMajor() >= 9); + Assume.assumeTrue(System.getProperty("jdk.module.path") != null); + WebInfConfiguration config = new WebInfConfiguration(); + WebAppContext context = new WebAppContext(); + context.setAttribute(JavaVersion.JAVA_TARGET_PLATFORM, "8"); + context.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, ".*/jetty-util-[^/]*\\.jar$|.*/jetty-util/target/classes/$|.*/foo-bar-janb.jar"); + WebAppClassLoader loader = new WebAppClassLoader(context); + context.setClassLoader(loader); + config.findAndFilterContainerPaths(context); + List containerResources = context.getMetaData().getContainerResources(); + assertEquals(1, containerResources.size()); + assertTrue(containerResources.get(0).toString().contains("jetty-util")); + } + +} diff --git a/jetty-webapp/src/test/resources/mods/com-acme-janb.jar b/jetty-webapp/src/test/resources/mods/com-acme-janb.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4d2b89004d84aecc55554748767b5e704c11b6f GIT binary patch literal 1772 zcmWIWW@Zs#;Nak3h^bBYW*(j{<{BKL=j$eV%9^i1frsJ3+!pJSD~yX4_ZUf=fA2Cq_`y)Odwclv?_xS1 zRWj3*r$ux(U*wCbRLd!u@w3ptal28Q%LDEEQ#aPGzn*n4qQ_t3k;0W6!<0?p)9(IT zG&M{gr5v#j!w)+i8M8+1&h;(wtP?%)GRGz2uz4;^NR=TfQa-f!6y!n3aC8 z&pQyeLT8Qd8y_E=gB{(BjlL=o)q33g4;J?9?v|RXsrG(vewy6*+p-6k7!T?`S$OWK zjjnKJGsk0j+EB;$)b{_*nS{!w{J03f^NKXH)sdH#WqS>5j ztLJF5{;UsJA}q~!FzduKuN92}%#1coi}$xzuXAZoY@EiTKQYMixw*+sCf%A$`Oi z=jQ@-FtcD+!3kB7n4Fu6M;RZovaH0sB(PdYGKxS;MiLlmeG@bDAfetHayv-aQNZ@F zs`Rv02L%O<4h{*22>l1T99|-f!dp2GG5b$G>mfF2?v-~ePyPS!)^>>S*EPte-ki-V zn$+|(>}^by-}gC}jW6%7oBy9>L(g`rDuXMni7}TAn=WcZ9xuIfq@^!<#+TW*6MbIJ zIM$QDPuMNy@R~NuwhLWvZ)8nfXlu9o_=Sm6EDs8J-t4Og*Gp^NeR?zNrV^2zZw+{k z@&~#9X_?LXPG*+m(_7~f50zgr-t;Ca>F~FMv6)Qzzbu&dc4W*jFA(RJ662k*PPK2kBC(Vr&xZS zq7jtU@;c~&!w%iE{7a%HmL2ToZ2PAcH)ZYlt9b@?x98}}>Tf)kkRx29q+6VNN@At< zr{sxK`i@@RxAv3CCy{ay!TFurPgHE~OkBWf&$jl-c`g;RYg!lLnjhV@v3x2~wPw?6 zF8A0o(yc6Ew+zcPL<~b8b+3A6rCRA1u*yy9!SrcDXP*~8yzINNtR;M}E6?Qc?y?pm z`*%x(>N&a2^|NGp{JQ>v_i#w<)iS>)8&|k;UD|U{SM_c%Z}b|m=uc~a1>UnT1uSh*y;9kgs85wESQy;&}^xV=Qzh%ND8Kslltvzd9oDQ2E{!(9< zEb-sG?^LrR>yiJr4*X&F&XqrVY(@H&@^gO~e!DU6dUK_1m0PctuL!fLhWd50{SvkA zwK=3-*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48BtF{Df z2)Xb<-^=HmXK2AWeXSGvUOJ4cEshe@4uR=t%9ykAkg+2At zGv++|Khu2X_1_;^Hn{q9tlK3awRPpKpx+9IKIsc=-Q($0amji5>e{OsPBk0;XngLr zSv}7{f2*JI&81s&HjCOcnTNTlNN_d_v9uh}DY~+nMX<4~JfUg5%npNl2dAv(Zt9n; z&u*FaS?RmD+5eZ!pkNi``fz*((9!3h-r{0l00y-TTAZ)|Wz+KW^+6uTt^yQ4AQef8 zMR-*4BB{zs%u50*g(L%XE5*^3hG!&}K*BS&Z*Sfq1CiGAs*0SNPyO!-FiV%LSnlUq z;*jK&%5X5JnbG~q#6=A2ulh}usA#Ygd1U3ZDkR$K`oAwPZ|uMRne~A7EW;Wbw-v1` z+A{>28aJxR3+;)kcl_Y~GD`TBaPrsV4})Lk=v|%HS%2%~oDWxC`wLZ0Nz#8CcIMNW z8*il*=Phl|S$h1~%BiZW_0O$Z)YEXk;K5$+jJ!)B8Z$dxqEx53CO=-Ew@PU5sf(@0 z=a;NzDdL@@c;CvVGyUgJ_Ah7IosLL~TySnJuL-}+ntV&E_OGz=x%Nf7tHALgr{sP7 z2GHwbjG$!3$RxsmnoD3=0F+Bm0X*4*@(j9GO%l_V5q|qH&`noEe3eAvVjz`1K|>&4Jyna9suqYMlJvV literal 0 HcmV?d00001 From 98d8c2400ddca714ddfdf7e5a78a177a53798f89 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 16 Nov 2017 10:01:44 +0100 Subject: [PATCH 2/2] Issue #1933 Add some comments, changes from code review. Signed-off-by: Jan Bartel --- .../eclipse/jetty/annotations/AnnotationConfiguration.java | 4 ++-- .../src/main/java/org/eclipse/jetty/util/JavaVersion.java | 4 ++++ .../java/org/eclipse/jetty/webapp/WebInfConfiguration.java | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 6b8ace0cf5a..22571e6f2cd 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -73,7 +73,7 @@ public class AnnotationConfiguration extends AbstractConfiguration public static final String CONTAINER_INITIALIZER_STARTER = "org.eclipse.jetty.containerInitializerStarter"; public static final String MULTI_THREADED = "org.eclipse.jetty.annotations.multiThreaded"; public static final String MAX_SCAN_WAIT = "org.eclipse.jetty.annotations.maxWait"; - public static final String JAVA_TARGET_PLATFORM = JavaVersion.JAVA_TARGET_PLATFORM; + public static final int DEFAULT_MAX_SCAN_WAIT = 60; /* time in sec */ public static final boolean DEFAULT_MULTI_THREADED = true; @@ -421,7 +421,7 @@ public class AnnotationConfiguration extends AbstractConfiguration throws Exception { int javaPlatform = 0; - Object target = context.getAttribute(JAVA_TARGET_PLATFORM); + Object target = context.getAttribute(JavaVersion.JAVA_TARGET_PLATFORM); if (target!=null) javaPlatform = Integer.valueOf(target.toString()); AnnotationParser parser = createAnnotationParser(javaPlatform); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java index 0df8f900fde..4c977801162 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java @@ -28,6 +28,10 @@ import java.util.regex.Pattern; public class JavaVersion { + /** + * Context attribute that can be set to target a different version of the jvm than the current runtime. + * Acceptable values should correspond to those returned by JavaVersion.getPlatform(). + */ public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform"; // Copy of version in jetty-start diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index 5a9f7895ac6..9e6d92f2698 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -226,7 +226,7 @@ public class WebInfConfiguration extends AbstractConfiguration //if running on jvm 9 or above, we we won't be able to look at the application classloader //to extract urls, so we need to examine the classpath instead. - if (JavaVersion.VERSION.getMajor() >= 9) + if (JavaVersion.VERSION.getPlatform() >= 9) { tmp = System.getProperty("java.class.path"); if (tmp != null)