forked from I2P_Developers/i2p.i2p
Jetty: Support annotation scanning of plugins for Servlet 3.0 @WebServlet
Requires 4 jars not yet bundled: asm.jar javax-annotations-api.jar jetty-annotations.jar jetty-plus.jar
This commit is contained in:
@ -717,7 +717,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
}
|
}
|
||||||
WebAppContext wac = (WebAppContext)(rootWebApp.getHandler());
|
WebAppContext wac = (WebAppContext)(rootWebApp.getHandler());
|
||||||
initialize(_context, wac);
|
initialize(_context, wac);
|
||||||
WebAppStarter.setWebAppConfiguration(wac);
|
WebAppStarter.setWebAppConfiguration(wac, false);
|
||||||
chColl.addHandler(rootWebApp);
|
chColl.addHandler(rootWebApp);
|
||||||
|
|
||||||
} catch (Exception ioe) {
|
} catch (Exception ioe) {
|
||||||
|
@ -2,8 +2,13 @@ package net.i2p.router.web;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
@ -38,7 +43,23 @@ public class WebAppStarter {
|
|||||||
|
|
||||||
private static final Map<String, Long> warModTimes = new ConcurrentHashMap<String, Long>();
|
private static final Map<String, Long> warModTimes = new ConcurrentHashMap<String, Long>();
|
||||||
static final Map<String, String> INIT_PARAMS = new HashMap<String, String>(4);
|
static final Map<String, String> INIT_PARAMS = new HashMap<String, String>(4);
|
||||||
//static private Log _log;
|
|
||||||
|
// There are 4 additional jars that are required to do the Servlet 3.0 annotation scanning.
|
||||||
|
// The following 4 classes were the first to get thrown as not found, for each jar.
|
||||||
|
// So use them to see if we have the 4 jars.
|
||||||
|
// jetty-annotations.jar
|
||||||
|
private static final String CLASS_ANNOT = "org.eclipse.jetty.annotations.AnnotationConfiguration";
|
||||||
|
// jetty-plus.jar
|
||||||
|
private static final String CLASS_ANNOT2 = "org.eclipse.jetty.plus.annotation.LifeCycleCallback";
|
||||||
|
// asm.jar
|
||||||
|
private static final String CLASS_ANNOT3 = "org.objectweb.asm.Type";
|
||||||
|
// javax-annotations-api.jar
|
||||||
|
private static final String CLASS_ANNOT4 = "javax.annotation.security.RunAs";
|
||||||
|
|
||||||
|
private static final String CLASS_CONFIG = "org.eclipse.jetty.webapp.JettyWebXmlConfiguration";
|
||||||
|
|
||||||
|
private static final boolean HAS_ANNOTATION_CLASSES;
|
||||||
|
private static final Set<String> BUILTINS = new HashSet<String>(8);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
//_log = ContextHelper.getContext(null).logManager().getLog(WebAppStarter.class); ;
|
//_log = ContextHelper.getContext(null).logManager().getLog(WebAppStarter.class); ;
|
||||||
@ -46,6 +67,20 @@ public class WebAppStarter {
|
|||||||
String pfx = "org.eclipse.jetty.servlet.Default.";
|
String pfx = "org.eclipse.jetty.servlet.Default.";
|
||||||
INIT_PARAMS.put(pfx + "cacheControl", "max-age=86400");
|
INIT_PARAMS.put(pfx + "cacheControl", "max-age=86400");
|
||||||
INIT_PARAMS.put(pfx + "dirAllowed", "false");
|
INIT_PARAMS.put(pfx + "dirAllowed", "false");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
try {
|
||||||
|
Class<?> cls = Class.forName(CLASS_ANNOT, false, ClassLoader.getSystemClassLoader());
|
||||||
|
cls = Class.forName(CLASS_ANNOT2, false, ClassLoader.getSystemClassLoader());
|
||||||
|
cls = Class.forName(CLASS_ANNOT3, false, ClassLoader.getSystemClassLoader());
|
||||||
|
cls = Class.forName(CLASS_ANNOT4, false, ClassLoader.getSystemClassLoader());
|
||||||
|
found = true;
|
||||||
|
} catch (Exception e) {}
|
||||||
|
HAS_ANNOTATION_CLASSES = found;
|
||||||
|
|
||||||
|
// don't scan these wars
|
||||||
|
BUILTINS.addAll(Arrays.asList(new String[] {"i2psnark", "i2ptunnel", "imagegen", "jsonrpc",
|
||||||
|
"routerconsole", "susidns", "susimail"} ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -115,20 +150,31 @@ public class WebAppStarter {
|
|||||||
tmpdir.mkdir();
|
tmpdir.mkdir();
|
||||||
wac.setTempDirectory(tmpdir);
|
wac.setTempDirectory(tmpdir);
|
||||||
// all the JSPs are precompiled, no need to extract
|
// all the JSPs are precompiled, no need to extract
|
||||||
wac.setExtractWAR(false);
|
// UNLESS it's a plugin and we want to scan it for annotations.
|
||||||
|
// We do not use Servlet 3.0 for any built-in wars.
|
||||||
|
// Jetty bug - annotation scanning fails unless we extract the war:
|
||||||
|
// org.eclipse.jetty.server.Server: Skipping scan on invalid file jar:file:/home/.../i2p/webapps/routerconsole.war!/WEB-INF/classes/net/i2p/router/web/servlets/CodedIconRendererServlet.class
|
||||||
|
// See AnnotationParser.isValidClassFileName()
|
||||||
|
// Server must be at DEBUG level to see what's happening
|
||||||
|
boolean scanAnnotations = HAS_ANNOTATION_CLASSES && !BUILTINS.contains(appName);
|
||||||
|
System.out.println("Scanning " + appName + " for annotations? " + scanAnnotations);
|
||||||
|
wac.setExtractWAR(scanAnnotations);
|
||||||
|
|
||||||
// this does the passwords...
|
// this does the passwords...
|
||||||
RouterConsoleRunner.initialize(ctx, wac);
|
RouterConsoleRunner.initialize(ctx, wac);
|
||||||
setWebAppConfiguration(wac);
|
setWebAppConfiguration(wac, scanAnnotations);
|
||||||
server.addHandler(wac);
|
server.addHandler(wac);
|
||||||
server.mapContexts();
|
server.mapContexts();
|
||||||
return wac;
|
return wac;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param scanAnnotations Should we check for Servlet 3.0 annotations?
|
||||||
|
* The war MUST be set to extract (due to Jetty bug),
|
||||||
|
* and annotation classes MUST be available
|
||||||
* @since Jetty 9
|
* @since Jetty 9
|
||||||
*/
|
*/
|
||||||
static void setWebAppConfiguration(WebAppContext wac) {
|
static void setWebAppConfiguration(WebAppContext wac, boolean scanAnnotations) {
|
||||||
// see WebAppConfiguration for info
|
// see WebAppConfiguration for info
|
||||||
String[] classNames = wac.getConfigurationClasses();
|
String[] classNames = wac.getConfigurationClasses();
|
||||||
// In Jetty 9, it doesn't set the defaults if we've already added one, but the
|
// In Jetty 9, it doesn't set the defaults if we've already added one, but the
|
||||||
@ -138,14 +184,24 @@ public class WebAppStarter {
|
|||||||
// See WebAppContext.loadConfigurations() in source
|
// See WebAppContext.loadConfigurations() in source
|
||||||
if (classNames.length == 0)
|
if (classNames.length == 0)
|
||||||
classNames = wac.getDefaultConfigurationClasses();
|
classNames = wac.getDefaultConfigurationClasses();
|
||||||
String[] newClassNames = new String[classNames.length + 1];
|
List<String> newClassNames = new ArrayList<String>(Arrays.asList(classNames));
|
||||||
for (int j = 0; j < classNames.length; j++) {
|
for (String name : newClassNames) {
|
||||||
newClassNames[j] = classNames[j];
|
|
||||||
// fix for Jetty 9.4 ticket #2385
|
// fix for Jetty 9.4 ticket #2385
|
||||||
wac.prependServerClass("-" + classNames[j]);
|
wac.prependServerClass("-" + name);
|
||||||
}
|
}
|
||||||
newClassNames[classNames.length] = WebAppConfiguration.class.getName();
|
// https://www.eclipse.org/jetty/documentation/current/using-annotations.html
|
||||||
wac.setConfigurationClasses(newClassNames);
|
// https://www.eclipse.org/jetty/documentation/9.4.x/using-annotations-embedded.html
|
||||||
|
if (scanAnnotations) {
|
||||||
|
if (!newClassNames.contains(CLASS_ANNOT)) {
|
||||||
|
int idx = newClassNames.indexOf(CLASS_CONFIG);
|
||||||
|
if (idx >= 0)
|
||||||
|
newClassNames.add(idx, CLASS_ANNOT);
|
||||||
|
else
|
||||||
|
newClassNames.add(CLASS_ANNOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newClassNames.add(WebAppConfiguration.class.getName());
|
||||||
|
wac.setConfigurationClasses(newClassNames.toArray(new String[newClassNames.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user