diff --git a/VERSION.txt b/VERSION.txt index 6d337e91fcc..75754629646 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-9.0.4-SNAPSHOT + jetty-9.0.3.v20130506 06 May 2013 + 404010 fix cast exception in mongodb session manager + 404911 WebSocketCloseTest fails spuriously @@ -164,6 +166,34 @@ jetty-9.0.0.v20130308 - 08 March 2013 + 402757 WebSocket client module can't be used with WebSocket server module in the same WAR +jetty-8.1.11.v20130520 - 20 May 2013 + + 402844 STOP.PORT & STOP.KEY behaviour has changed + + 403281 jetty.sh waits for started or failure before returning + + 403513 jetty:run goal cannot be executed twice during the maven build + + 403570 Asynchronous Request Logging + + 404010 fix cast exception in mongodb session manager + + 404128 Add Vary headers rather than set them + + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if + listFiles() returns null + + 404325 data constraint redirection does send default port + + 404517 Close connection if request received after half close + + 404789 Support IPv6 addresses in DoSFilter white list. + + 404958 Fixed Resource.newSystemResource striped / handling + + 405281 allow filemappedbuffers to not be used + + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest + + 406437 Digest Auth supports out of order nc + + 406618 Jetty startup in OSGi Equinox fails when using option + jetty.home.bundle=org.eclipse.jetty.osgi.boot + + 406923 CR line termination + + 407136 @PreDestroy called after Servlet.destroy() + + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager + + 407931 Add toggle for failing on servlet availability + + 407976 JDBCSessionIdManager potentially leaves server in bad state after + startup + + 408077 HashSessionManager leaves file handles open after being stopped + + 408446 Multipart parsing issue with boundry and charset in ContentType + header + jetty-8.1.10.v20130312 - 12 March 2013 + 376273 Early EOF because of SSL Protocol Error on https://api-3t.paypal.com/nvp. @@ -200,6 +230,31 @@ jetty-8.1.10.v20130312 - 12 March 2013 + 402833 Test harness for global error page and hide exception message from reason string +jetty-7.6.11.v20130520 - 20 May 2013 + + 402844 STOP.PORT & STOP.KEY behaviour has changed + + 403281 jetty.sh waits for started or failure before returning + + 403513 jetty:run goal cannot be executed twice during the maven build + + 403570 Asynchronous Request Logging + + 404010 fix cast exception in mongodb session manager + + 404128 Add Vary headers rather than set them + + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if + listFiles() returns null + + 404325 data constraint redirection does send default port + + 404517 Close connection if request received after half close + + 404789 Support IPv6 addresses in DoSFilter white list. + + 404958 Fixed Resource.newSystemResource striped / handling + + 405281 allow filemappedbuffers to not be used + + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest + + 406437 Digest Auth supports out of order nc + + 406923 CR line termination + + 407136 @PreDestroy called after Servlet.destroy() + + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager + + 407976 JDBCSessionIdManager potentially leaves server in bad state after + startup + + 408077 HashSessionManager leaves file handles open after being stopped + + 408446 Multipart parsing issue with boundry and charset in ContentType + header + jetty-7.6.10.v20130312 - 12 March 2013 + 376273 Early EOF because of SSL Protocol Error on https://api-3t.paypal.com/nvp. diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java index 3a0cadc5282..dca34758fcf 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebAppContext.java @@ -21,11 +21,20 @@ package org.eclipse.jetty.ant; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.net.URI; import java.net.URL; import java.net.URLClassLoader; +import java.security.CodeSource; +import java.security.PermissionCollection; import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; +import java.util.jar.Manifest; import javax.servlet.Servlet; @@ -44,6 +53,8 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.Holder; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.Configuration; import org.eclipse.jetty.webapp.FragmentConfiguration; @@ -65,6 +76,8 @@ import org.eclipse.jetty.xml.XmlConfiguration; */ public class AntWebAppContext extends WebAppContext { + private static final Logger LOG = Log.getLogger(WebAppContext.class); + public final AntWebInfConfiguration antWebInfConfiguration = new AntWebInfConfiguration(); public final WebXmlConfiguration webXmlConfiguration = new WebXmlConfiguration(); public final MetaInfConfiguration metaInfConfiguration = new MetaInfConfiguration(); @@ -142,6 +155,184 @@ public class AntWebAppContext extends WebAppContext } + /** + * AntURLClassLoader + * + * Adapt the AntClassLoader which is not a URLClassLoader - this is needed for + * jsp to be able to search the classpath. + */ + public static class AntURLClassLoader extends URLClassLoader + { + private AntClassLoader antLoader; + + public AntURLClassLoader(AntClassLoader antLoader) + { + super(new URL[] {}, antLoader); + this.antLoader = antLoader; + } + + @Override + public InputStream getResourceAsStream(String name) + { + return super.getResourceAsStream(name); + } + + @Override + public void close() throws IOException + { + super.close(); + } + + @Override + protected void addURL(URL url) + { + super.addURL(url); + } + + @Override + public URL[] getURLs() + { + Set urls = new HashSet(); + + //convert urls from antLoader + String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar})); + if (paths != null) + { + for (String p:paths) + { + File f = new File(p); + try + { + urls.add(f.toURI().toURL()); + } + catch (Exception e) + { + LOG.ignore(e); + } + } + } + + //add in any that may have been added to us as a URL directly + URL[] ourURLS = super.getURLs(); + if (ourURLS != null) + { + for (URL u:ourURLS) + urls.add(u); + } + + return urls.toArray(new URL[urls.size()]); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException + { + return super.findClass(name); + } + + @Override + protected Package definePackage(String name, Manifest man, URL url) throws IllegalArgumentException + { + return super.definePackage(name, man, url); + } + + @Override + public URL findResource(String name) + { + return super.findResource(name); + } + + @Override + public Enumeration findResources(String name) throws IOException + { + return super.findResources(name); + } + + @Override + protected PermissionCollection getPermissions(CodeSource codesource) + { + return super.getPermissions(codesource); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException + { + return super.loadClass(name); + } + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException + { + return super.loadClass(name, resolve); + } + + @Override + protected Object getClassLoadingLock(String className) + { + return super.getClassLoadingLock(className); + } + + @Override + public URL getResource(String name) + { + return super.getResource(name); + } + + @Override + public Enumeration getResources(String name) throws IOException + { + return super.getResources(name); + } + + @Override + protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, + String implVendor, URL sealBase) throws IllegalArgumentException + { + return super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase); + } + + @Override + protected Package getPackage(String name) + { + return super.getPackage(name); + } + + @Override + protected Package[] getPackages() + { + return super.getPackages(); + } + + @Override + protected String findLibrary(String libname) + { + return super.findLibrary(libname); + } + + @Override + public void setDefaultAssertionStatus(boolean enabled) + { + super.setDefaultAssertionStatus(enabled); + } + + @Override + public void setPackageAssertionStatus(String packageName, boolean enabled) + { + super.setPackageAssertionStatus(packageName, enabled); + } + + @Override + public void setClassAssertionStatus(String className, boolean enabled) + { + super.setClassAssertionStatus(className, enabled); + } + + @Override + public void clearAssertionStatus() + { + super.clearAssertionStatus(); + } + } + /** * AntServletHolder @@ -180,31 +371,6 @@ public class AntWebAppContext extends WebAppContext super(name, servlet); } - - @Override - protected void initJspServlet() throws Exception - { - //super.initJspServlet(); - - ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext()); - - /* Set the webapp's classpath for Jasper */ - ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath()); - - /* Set the system classpath for Jasper */ - String sysClassPath = getSystemClassPath(ch.getClassLoader().getParent()); - setInitParameter("com.sun.appserv.jsp.classpath", sysClassPath); - - /* Set up other classpath attribute */ - if ("?".equals(getInitParameter("classpath"))) - { - String classpath = ch.getClassPath(); - if (classpath != null) - setInitParameter("classpath", classpath); - } - } - - protected String getSystemClassPath (ClassLoader loader) throws Exception { StringBuilder classpath=new StringBuilder(); @@ -465,7 +631,7 @@ public class AntWebAppContext extends WebAppContext /** - * @see WebApplicationProxy#start() + * */ public void doStart() { @@ -474,7 +640,12 @@ public class AntWebAppContext extends WebAppContext TaskLog.logWithTimestamp("Starting web application "+this.getDescriptor()); if (jettyEnvXml != null && jettyEnvXml.exists()) envConfiguration.setJettyEnvXml(Resource.toURL(jettyEnvXml)); - setClassLoader(new WebAppClassLoader(this.getClass().getClassLoader(), this)); + + ClassLoader parentLoader = this.getClass().getClassLoader(); + if (parentLoader instanceof AntClassLoader) + parentLoader = new AntURLClassLoader((AntClassLoader)parentLoader); + + setClassLoader(new WebAppClassLoader(parentLoader, this)); if (attributes != null && attributes.getAttributes() != null) { for (Attribute a:attributes.getAttributes()) diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java index b1aa27965a5..0e03150c5ef 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/ServerProxyImpl.java @@ -278,6 +278,7 @@ public class ServerProxyImpl implements ServerProxy } catch (Exception e) { + e.printStackTrace(); new RuntimeException(e); } } @@ -351,11 +352,14 @@ public class ServerProxyImpl implements ServerProxy return; configured = true; - - ShutdownMonitor monitor = ShutdownMonitor.getInstance(); - monitor.setPort(stopPort); - monitor.setKey(stopKey); - monitor.setExitVm(false); + + if(stopPort>0 && stopKey!=null) + { + ShutdownMonitor monitor = ShutdownMonitor.getInstance(); + monitor.setPort(stopPort); + monitor.setKey(stopKey); + monitor.setExitVm(false); + } if (tempDirectory != null && !tempDirectory.exists()) tempDirectory.mkdirs(); diff --git a/jetty-ant/src/test/config/build.xml b/jetty-ant/src/test/config/build.xml index aab02444a9d..9ca5fedf5bd 100644 --- a/jetty-ant/src/test/config/build.xml +++ b/jetty-ant/src/test/config/build.xml @@ -7,11 +7,10 @@ - + - - - + + @@ -30,12 +29,12 @@ - - + + diff --git a/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java b/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java index 3a81130c708..ec70c7c80ac 100644 --- a/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java +++ b/jetty-ant/src/test/java/org/eclipse/jetty/ant/JettyAntTaskTest.java @@ -30,8 +30,7 @@ import org.junit.Test; public class JettyAntTaskTest { - @Ignore - //@Test + @Test public void testConnectorTask() throws Exception { AntBuild build = new AntBuild(MavenTestingUtils.getTestResourceFile("connector-test.xml").getAbsolutePath()); @@ -51,7 +50,6 @@ public class JettyAntTaskTest @Test - @Ignore("need to update connector") public void testWebApp () throws Exception { AntBuild build = new AntBuild(MavenTestingUtils.getTestResourceFile("webapp-test.xml").getAbsolutePath()); diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java index 407b85628b2..8fc683e42dd 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/TagLibOSGiConfiguration.java @@ -25,7 +25,7 @@ import java.util.Enumeration; import java.util.LinkedHashSet; import org.eclipse.jetty.osgi.boot.OSGiWebappConstants; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -115,24 +115,24 @@ public class TagLibOSGiConfiguration extends TagLibConfiguration { atLeastOneTldFound = true; URL oriUrl = en.nextElement(); - URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(oriUrl); - Resource tldResource; try { + URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(oriUrl); + Resource tldResource; tldResource = Resource.newResource(url); + tlds.add(tldResource); } - catch (IOException e) + catch (Exception e) { throw new IllegalArgumentException("Unable to locate the " + "tld resource in '" - + url.toString() - + "' in the bundle '" - + bs[0].getSymbolicName() - + "' while registering the " - + OSGiWebappConstants.REQUIRE_TLD_BUNDLE - + " of the manifest of " - + bundle.getSymbolicName(), e); + + oriUrl.toString() + + "' in the bundle '" + + bs[0].getSymbolicName() + + "' while registering the " + + OSGiWebappConstants.REQUIRE_TLD_BUNDLE + + " of the manifest of " + + bundle.getSymbolicName(), e); } - tlds.add(tldResource); } if (!atLeastOneTldFound) { diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-selector.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-selector.xml index badf00e976d..67cd87c2a7e 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-selector.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-selector.xml @@ -12,6 +12,15 @@ + + + + + + + + + 300000 diff --git a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml index 1c998353866..4bde8d7222e 100644 --- a/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml +++ b/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty.xml @@ -14,7 +14,7 @@ - + 10 @@ -44,6 +44,17 @@ + + https + + 32768 + 8192 + 8192 + true + false + 512 + + diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java index 5d801c614eb..b15d6179dbc 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractContextProvider.java @@ -27,7 +27,7 @@ import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -214,7 +214,7 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen //put the server instance in properties.put("Server", getServerInstanceWrapper().getServer()); //put in the location of the bundle root - properties.put("bundle.root", rootResource.toString()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); // insert the bundle's location as a property. xmlConfiguration.getProperties().putAll(properties); diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java index cbae1c92d8b..03d3dcc0e32 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/AbstractWebAppProvider.java @@ -28,12 +28,14 @@ import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.JarResource; +import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; import org.osgi.framework.Bundle; @@ -195,7 +197,15 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement ? BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle) : new File(overrideBundleInstallLocation)); URL url = null; - + Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(bundleInstallLocation.toURI().toURL())); + //try and make sure the rootResource is useable - if its a jar then make it a jar file url + if (rootResource.exists()&& !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) + { + Resource jarResource = JarResource.newJarResource(rootResource); + if (jarResource.exists() && jarResource.isDirectory()) + rootResource = jarResource; + } + //if the path wasn't set or it was ., then it is the root of the bundle's installed location if (_webAppPath == null || _webAppPath.length() == 0 || ".".equals(_webAppPath)) { @@ -227,6 +237,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement + (bundleInstallLocation != null ? bundleInstallLocation.getAbsolutePath() : "unlocated bundle '" + _bundle.getSymbolicName()+ "'")); } + //Sets the location of the war file // converts bundleentry: protocol if necessary _webApp.setWar(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url).toString()); @@ -283,7 +294,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement // apply any META-INF/context.xml file that is found to configure // the webapp first - applyMetaInfContextXml(); + applyMetaInfContextXml(rootResource); // pass the value of the require tld bundle so that the TagLibOSGiConfiguration // can pick it up. @@ -341,7 +352,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement } - protected void applyMetaInfContextXml() + protected void applyMetaInfContextXml(Resource rootResource) throws Exception { if (_bundle == null) return; @@ -365,6 +376,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl); HashMap properties = new HashMap(); properties.put("Server", getDeploymentManager().getServer()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); xmlConfiguration.getProperties().putAll(properties); xmlConfiguration.configure(_webApp); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java index 9767bd310c8..197ee2cb2cb 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiMetaInfConfiguration.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.List; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java index 76eb8ade44d..b606db40fa1 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java @@ -27,7 +27,7 @@ import java.util.StringTokenizer; import java.util.TreeMap; import java.util.regex.Pattern; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java index e97457aecdf..cedaf3bf3ed 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebappConstants.java @@ -79,6 +79,10 @@ public class OSGiWebappConstants public static final String JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH = "Jetty-WarPatchFragmentFolderPath"; + /** installation path of webapp bundle + * + */ + public static final String JETTY_BUNDLE_ROOT = "bundle.root"; /** * web app context path * @deprecated see RFC66_WEB_CONTEXTPATH diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index f20838b7625..8d02dd2a9cb 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -20,18 +20,25 @@ package org.eclipse.jetty.osgi.boot.internal.serverfactory; import java.io.File; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; +import java.util.ArrayList; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.StringTokenizer; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader; +import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.JarResource; +import org.eclipse.jetty.util.resource.Resource; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -63,7 +70,7 @@ public class DefaultJettyAtJettyHomeHelper /** * Default location within bundle of a jetty home dir. */ - public static final String DEFAULT_JETTYHOME = "/jettyhome/"; + public static final String DEFAULT_JETTYHOME = "/jettyhome"; @@ -80,9 +87,7 @@ public class DefaultJettyAtJettyHomeHelper * In both cases reads the system property 'jetty.etc.config.urls' to locate * the configuration files for the deployed jetty. It is a comma separated * list of URLs or relative paths inside the bundle or folder to the config - * files. If undefined it defaults to 'etc/jetty.xml'. In the case of the jetty.home.bundle, - * if no etc/jetty.xml file is found in the bundle, it will look for - * /jettyhome/etc/jetty-osgi-default.xml + * files. *

*

* In both cases the system properties jetty.host, jetty.port and @@ -94,30 +99,33 @@ public class DefaultJettyAtJettyHomeHelper { String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME); String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE); - File jettyHome = null; + File jettyHomeDir = null; Bundle jettyHomeBundle = null; + + Dictionary properties = new Hashtable(); if (jettyHomeSysProp != null) { - jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); + jettyHomeSysProp = Util.resolvePropertyValue(jettyHomeSysProp); // bug 329621 if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) - { jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); - } + if (jettyHomeBundleSysProp != null) - { LOG.warn("Both jetty.home and jetty.home.bundle property defined: jetty.home.bundle ignored."); - } - jettyHome = new File(jettyHomeSysProp); - if (!jettyHome.exists() || !jettyHome.isDirectory()) + + jettyHomeDir = new File(jettyHomeSysProp); + if (!jettyHomeDir.exists() || !jettyHomeDir.isDirectory()) { LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); return null; } + + //set jetty.home + Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, jettyHomeDir.getAbsolutePath()); } else if (jettyHomeBundleSysProp != null) { - jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp); + jettyHomeBundleSysProp = Util.resolvePropertyValue(jettyHomeBundleSysProp); for (Bundle b : bundleContext.getBundles()) { if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) @@ -131,38 +139,52 @@ public class DefaultJettyAtJettyHomeHelper LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); return null; } - } - if (jettyHome == null && jettyHomeBundle == null) + + if (jettyHomeDir == null && jettyHomeBundle == null) { LOG.warn("No default jetty created."); return null; } - - Server server = new Server(); - Dictionary properties = new Hashtable(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - - String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle); - properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); - - LOG.info("Configuring the default jetty server with " + configURLs); - - // these properties usually are the ones passed to this type of - // configuration. - setProperty(properties, OSGiServerConstants.JETTY_HOME, System.getProperty(OSGiServerConstants.JETTY_HOME)); - setProperty(properties, OSGiServerConstants.JETTY_HOST, System.getProperty(OSGiServerConstants.JETTY_HOST)); - setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT)); - setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL)); - - //Register the default Server instance as an OSGi service. - //The JettyServerServiceTracker will notice it and configure it. - bundleContext.registerService(Server.class.getName(), server, properties); - return server; + + + //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to + //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing + List configURLs = jettyHomeDir != null ? getJettyConfigurationURLs(jettyHomeDir) : getJettyConfigurationURLs(jettyHomeBundle, properties); + + LOG.info("Configuring the default jetty server with {}",configURLs); + LOG.info("JETTY.HOME="+properties.get(OSGiServerConstants.JETTY_HOME)); + ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(JettyBootstrapActivator.class.getClassLoader()); + + // these properties usually are the ones passed to this type of + // configuration. + properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); + Util.setProperty(properties, OSGiServerConstants.JETTY_HOST, System.getProperty(OSGiServerConstants.JETTY_HOST)); + Util.setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT)); + Util.setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL)); + + Server server = ServerInstanceWrapper.configure(null, configURLs, properties); + //ensure jetty.home is set + server.setAttribute(OSGiServerConstants.JETTY_HOME, properties.get(OSGiServerConstants.JETTY_HOME)); + + //Register the default Server instance as an OSGi service. + //The JettyServerServiceTracker will notice it and set it up to deploy bundles as wars etc + bundleContext.registerService(Server.class.getName(), server, properties); + LOG.info("Default jetty server configured"); + return server; + } + finally + { + Thread.currentThread().setContextClassLoader(contextCl); + } } + - + /* ------------------------------------------------------------ */ /** @@ -173,33 +195,26 @@ public class DefaultJettyAtJettyHomeHelper * * @param jettyhome * @return + * @throws MalformedURLException */ - private static String getJettyConfigurationURLs(File jettyhome) + private static List getJettyConfigurationURLs(File jettyhome) + throws MalformedURLException { + List configURLs = new ArrayList(); String jettyetc = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES); StringTokenizer tokenizer = new StringTokenizer(jettyetc, ";,", false); - StringBuilder res = new StringBuilder(); while (tokenizer.hasMoreTokens()) { String next = tokenizer.nextToken().trim(); - if (!next.startsWith("/") && next.indexOf(':') == -1) - { - try - { - next = new File(jettyhome, next).toURI().toURL().toString(); - } - catch (MalformedURLException e) - { - LOG.warn(e); - continue; - } - } - appendToCommaSeparatedList(res, next); + //etc files can either be relative to jetty.home or absolute disk locations + if (!next.startsWith("/") && (next.indexOf(':') == -1)) + configURLs.add(new File(jettyhome, next).toURI().toURL()); + else + configURLs.add(new URL(next)); } - return res.toString(); + return configURLs; } - - + /* ------------------------------------------------------------ */ /** * Minimum setup for the location of the configuration files given a @@ -210,118 +225,90 @@ public class DefaultJettyAtJettyHomeHelper * @param jettyhome * @return */ - private static String getJettyConfigurationURLs(Bundle configurationBundle) + private static List getJettyConfigurationURLs(Bundle configurationBundle, Dictionary properties) + throws Exception { - String files = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES); - + List configURLs = new ArrayList(); + String files = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES); StringTokenizer tokenizer = new StringTokenizer(files, ";,", false); - StringBuilder res = new StringBuilder(); while (tokenizer.hasMoreTokens()) { String etcFile = tokenizer.nextToken().trim(); + + //file path is absolute if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1) + configURLs.add(new URL(etcFile)); + else //relative file path { - //file path is absolute - appendToCommaSeparatedList(res, etcFile); - } - else - { - //relative file path Enumeration enUrls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(configurationBundle, etcFile); - + + String home = null; // default for org.eclipse.osgi.boot where we look inside - // jettyhome for the default embedded configuration. - // default inside jettyhome. this way fragments to the bundle - // can define their own configuration. + // jettyhome/ for the default embedded configuration. if ((enUrls == null || !enUrls.hasMoreElements())) { + home = DEFAULT_JETTYHOME; String tmp = DEFAULT_JETTYHOME+(DEFAULT_JETTYHOME.endsWith("/")?"":"/")+etcFile; enUrls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(configurationBundle, tmp); - LOG.info("Configuring jetty from bundle: " - + configurationBundle.getSymbolicName() - + " with "+tmp); + LOG.info("Configuring jetty from bundle: {} with {}", configurationBundle.getSymbolicName(),tmp); + } + + //lazily ensure jetty.home value is set based on location of etc files + if (properties.get(OSGiServerConstants.JETTY_HOME) == null) + { + Resource res = findDir(configurationBundle, home); + if (res != null) + properties.put(OSGiServerConstants.JETTY_HOME, res.toString()); } + if (enUrls == null || !enUrls.hasMoreElements()) - { throw new IllegalStateException ("Unable to locate a jetty configuration file for " + etcFile); - } - if (enUrls != null) - { - while (enUrls.hasMoreElements()) - { - URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(enUrls.nextElement()); - appendToCommaSeparatedList(res, url.toString()); - } - } + + URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(enUrls.nextElement()); + configURLs.add(url); + } } - return res.toString(); + return configURLs; } - - /* ------------------------------------------------------------ */ - private static void appendToCommaSeparatedList(StringBuilder buffer, String value) - { - if (buffer.length() != 0) - { - buffer.append(","); - } - buffer.append(value); - } - - - /* ------------------------------------------------------------ */ - private static void setProperty(Dictionary properties, String key, String value) - { - if (value != null) - { - properties.put(key, value); - } - } - - /* ------------------------------------------------------------ */ /** - * recursively substitute the ${sysprop} by their actual system property. - * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no - * sysprop is defined. Not the most efficient code but we are shooting for - * simplicity and speed of development here. - * - * @param value + * Get a resource representing a directory inside a bundle. If the dir is null, + * return a resource representing the installation location of the bundle. + * @param bundle + * @param dir * @return */ - public static String resolvePropertyValue(String value) + public static Resource findDir (Bundle bundle, String dir) { - int ind = value.indexOf("${"); - if (ind == -1) { return value; } - int ind2 = value.indexOf('}', ind); - if (ind2 == -1) { return value; } - String sysprop = value.substring(ind + 2, ind2); - String defaultValue = null; - int comma = sysprop.indexOf(','); - if (comma != -1 && comma + 1 != sysprop.length()) - { - defaultValue = sysprop.substring(comma + 1); - defaultValue = resolvePropertyValue(defaultValue); - sysprop = sysprop.substring(0, comma); - } - else - { - defaultValue = "${" + sysprop + "}"; - } + if (bundle == null) + return null; - String v = System.getProperty(sysprop); - - String reminder = value.length() > ind2 + 1 ? value.substring(ind2 + 1) : ""; - reminder = resolvePropertyValue(reminder); - if (v != null) + try { - return value.substring(0, ind) + v + reminder; + File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); + URL u = f.toURI().toURL(); + u = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(u); + Resource res = Resource.newResource(u); + String s = res.toString(); + + //check if it is an unarchived bundle + if (s.endsWith(".jar") && s.startsWith("file:")) + res = JarResource.newJarResource(res); + + //if looking for a directory + if (dir != null) + res = res.addPath(dir); + + return res; + } - else + catch (Exception e) { - return value.substring(0, ind) + defaultValue + reminder; + LOG.warn("Bad bundle location" , e); + return null; } } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java deleted file mode 100644 index bb65462dffd..00000000000 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/IManagedJettyServerRegistry.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2013 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.osgi.boot.internal.serverfactory; - -/** - * Keeps track of the running jetty servers. They are named. - */ -public interface IManagedJettyServerRegistry -{ - - /** - * @param managedServerName The server name - * @return the corresponding jetty server wrapped with its deployment - * properties. - */ - public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName); - -} diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java index b946cd8da4b..37a5518a47c 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java @@ -38,15 +38,10 @@ import org.osgi.framework.ServiceReference; * webapps or ContextHandlers discovered from the OSGi environment. * */ -public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry +public class JettyServerServiceTracker implements ServiceListener { private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName()); - /** - * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin - * service. - */ - private Map _serversIndexedByName = new HashMap(); /** The context-handler to deactivate indexed by ServerInstanceWrapper */ private Map _indexByServiceReference = new HashMap(); @@ -56,8 +51,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty */ public void stop() { - // not sure that this is really useful but here we go. - for (ServerInstanceWrapper wrapper : _serversIndexedByName.values()) + for (ServerInstanceWrapper wrapper : _indexByServiceReference.values()) { try { @@ -136,7 +130,6 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); } ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name); _indexByServiceReference.put(sr, wrapper); - _serversIndexedByName.put(name, wrapper); return wrapper; } @@ -151,25 +144,10 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty ServerInstanceWrapper handler = _indexByServiceReference.remove(sr); if (handler == null) { - // a warning? + LOG.warn("Unknown Jetty Server ServiceReference: ", sr); return null; } - String name = handler.getManagedServerName(); - if (name != null) - { - _serversIndexedByName.remove(name); - } + return handler; } - - /** - * @param managedServerName The server name - * @return the corresponding jetty server wrapped with its deployment - * properties. - */ - public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName) - { - return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName); - } - } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java index 209fee6d9df..409be2f9e7f 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java @@ -45,10 +45,11 @@ import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.osgi.boot.OSGiUndeployer; import org.eclipse.jetty.osgi.boot.ServiceContextProvider; import org.eclipse.jetty.osgi.boot.ServiceWebAppProvider; -import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.internal.webapp.LibExtClassLoaderHelper; +import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.FakeURLClassLoader; import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer; +import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.util.IO; @@ -112,6 +113,87 @@ public class ServerInstanceWrapper return __containerTldBundleDiscoverers; } + + + + /* ------------------------------------------------------------ */ + public static Server configure(Server server, List jettyConfigurations, Dictionary props) throws Exception + { + + if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return server; } + + Map id_map = new HashMap(); + if (server != null) + { + //Put in a mapping for the id "Server" and the name of the server as the instance being configured + id_map.put("Server", server); + id_map.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server); + } + + Map properties = new HashMap(); + if (props != null) + { + Enumeration en = props.keys(); + while (en.hasMoreElements()) + { + Object key = en.nextElement(); + Object value = props.get(key); + String keyStr = String.valueOf(key); + String valStr = String.valueOf(value); + properties.put(keyStr, valStr); + if (server != null) server.setAttribute(keyStr, valStr); + } + } + + for (URL jettyConfiguration : jettyConfigurations) + { + InputStream is = null; + try + { + // Execute a Jetty configuration file + Resource r = Resource.newResource(jettyConfiguration); + if (!r.exists()) + { + LOG.warn("File does not exist "+r); + throw new IllegalStateException("No such jetty server config file: "+r); + } + is = r.getInputStream(); + XmlConfiguration config = new XmlConfiguration(is); + config.getIdMap().putAll(id_map); + config.getProperties().putAll(properties); + + // #334062 compute the URL of the folder that contains the + // conf file and set it as a property so we can compute relative paths + // from it. + String urlPath = jettyConfiguration.toString(); + int lastSlash = urlPath.lastIndexOf('/'); + if (lastSlash > 4) + { + urlPath = urlPath.substring(0, lastSlash); + config.getProperties().put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); + } + + Object o = config.configure(); + if (server == null) + server = (Server)o; + + id_map = config.getIdMap(); + } + catch (SAXParseException saxparse) + { + LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse); + throw saxparse; + } + finally + { + IO.close(is); + } + } + + return server; + } + + /* ------------------------------------------------------------ */ @@ -182,13 +264,16 @@ public class ServerInstanceWrapper String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); List shared = sharedURLs != null ? extractFiles(sharedURLs) : null; - libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader()); + libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null,JettyBootstrapActivator.class.getClassLoader()); if (LOG.isDebugEnabled()) LOG.debug("LibExtClassLoader = "+libExtClassLoader); Thread.currentThread().setContextClassLoader(libExtClassLoader); - configure(server, props); + String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); + List jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, Util.DEFAULT_DELIMS) : null; + + _server = configure(server, jettyConfigurations, props); init(); @@ -259,80 +344,6 @@ public class ServerInstanceWrapper - /* ------------------------------------------------------------ */ - private void configure(Server server, Dictionary props) throws Exception - { - String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); - List jettyConfigurations = jettyConfigurationUrls != null ? extractResources(jettyConfigurationUrls) : null; - if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; } - Map id_map = new HashMap(); - - //Put in a mapping for the id "Server" and the name of the server as the instance being configured - id_map.put("Server", server); - id_map.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server); - - Map properties = new HashMap(); - Enumeration en = props.keys(); - while (en.hasMoreElements()) - { - Object key = en.nextElement(); - Object value = props.get(key); - String keyStr = String.valueOf(key); - String valStr = String.valueOf(value); - properties.put(keyStr, valStr); - server.setAttribute(keyStr, valStr); - } - - for (URL jettyConfiguration : jettyConfigurations) - { - InputStream is = null; - try - { - // Execute a Jetty configuration file - Resource r = Resource.newResource(jettyConfiguration); - if (!r.exists()) - { - LOG.warn("File does not exist "+r); - continue; - } - is = r.getInputStream(); - XmlConfiguration config = new XmlConfiguration(is); - config.getIdMap().putAll(id_map); - - // #334062 compute the URL of the folder that contains the - // jetty.xml conf file - // and set it as a property so we can compute relative paths - // from it. - String urlPath = jettyConfiguration.toString(); - int lastSlash = urlPath.lastIndexOf('/'); - if (lastSlash > 4) - { - urlPath = urlPath.substring(0, lastSlash); - Map properties2 = new HashMap(properties); - properties2.put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); - config.getProperties().putAll(properties2); - } - else - { - config.getProperties().putAll(properties); - } - config.configure(); - id_map = config.getIdMap(); - } - catch (SAXParseException saxparse) - { - LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse); - throw saxparse; - } - finally - { - IO.close(is); - } - } - - } - - /* ------------------------------------------------------------ */ /** * Must be called after the server is configured. @@ -432,54 +443,8 @@ public class ServerInstanceWrapper } } - - /* ------------------------------------------------------------ */ - /** - * @return The default folder in which the context files of the osgi bundles - * are located and watched. Or null when the system property - * "jetty.osgi.contexts.home" is not defined. If the configuration - * file defines the OSGiAppProvider's context. This will not be - * taken into account. - */ - File getDefaultOSGiContextsHome(File jettyHome) - { - String jettyContextsHome = System.getProperty("jetty.osgi.contexts.home"); - if (jettyContextsHome != null) - { - File contextsHome = new File(jettyContextsHome); - if (!contextsHome.exists() || !contextsHome.isDirectory()) - { - throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" - + jettyContextsHome - + " must exist and be a folder"); - } - return contextsHome; - } - return new File(jettyHome, "/contexts"); - } - /* ------------------------------------------------------------ */ - /** - * @return the urls in this string. - */ - private List extractResources(String propertyValue) - { - StringTokenizer tokenizer = new StringTokenizer(propertyValue, ",;", false); - List urls = new ArrayList(); - while (tokenizer.hasMoreTokens()) - { - String tok = tokenizer.nextToken(); - try - { - urls.add(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(new URL(tok))); - } - catch (Throwable mfe) - { - LOG.warn(mfe); - } - } - return urls; - } + /* ------------------------------------------------------------ */ diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java index 76738348d7d..b728d214326 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java @@ -84,7 +84,7 @@ public class LibExtClassLoaderHelper * is the JettyBootStrapper (an osgi classloader. * @throws MalformedURLException */ - public static ClassLoader createLibEtcClassLoader(File jettyHome, Server server, ClassLoader parentClassLoader) throws MalformedURLException + public static ClassLoader createLibEtcClassLoader(File jettyHome, ClassLoader parentClassLoader) throws MalformedURLException { if (jettyHome == null) { return parentClassLoader; } ArrayList urls = new ArrayList(); @@ -141,7 +141,7 @@ public class LibExtClassLoaderHelper * extra jars to insert, then just return the parentClassLoader. * @throws MalformedURLException */ - public static ClassLoader createLibExtClassLoader(List jarsContainerOrJars, List otherJarsOrFolder, Server server, ClassLoader parentClassLoader) + public static ClassLoader createLibExtClassLoader(List jarsContainerOrJars, List otherJarsOrFolder, ClassLoader parentClassLoader) throws MalformedURLException { if (jarsContainerOrJars == null && otherJarsOrFolder == null) { return parentClassLoader; } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java index 08dbd4a9025..52d86c15581 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/ServiceWatcher.java @@ -185,7 +185,6 @@ public class ServiceWatcher implements ServiceListener try { added = e.getValue().serviceAdded(sr, contextHandler); - System.err.println(serverName+" deployed "+contextHandler+": "+added); if (added && LOG.isDebugEnabled()) LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java index 2abd7a0ab1d..911100f0922 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelper.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.osgi.boot.utils; import java.io.File; +import java.io.IOException; import java.net.URL; import java.util.Enumeration; @@ -103,7 +104,7 @@ public interface BundleFileLocatorHelper * * @return a URL to the bundle entry that uses a common protocol */ - public URL getLocalURL(URL url); + public URL getLocalURL(URL url) throws Exception; /** * Only useful for equinox: on felix we get the file:// url already. Other @@ -116,7 +117,9 @@ public interface BundleFileLocatorHelper * @return a URL to the content of the bundle entry that uses the file: * protocol *

+ * @throws IOException + * @throws Exception */ - public URL getFileURL(URL url); + public URL getFileURL(URL url) throws Exception; } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleFileLocatorHelperFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java similarity index 93% rename from jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleFileLocatorHelperFactory.java rename to jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java index 197008d8f07..233c2986c2a 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/BundleFileLocatorHelperFactory.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/BundleFileLocatorHelperFactory.java @@ -16,9 +16,8 @@ // ======================================================================== // -package org.eclipse.jetty.osgi.boot.internal.webapp; +package org.eclipse.jetty.osgi.boot.utils; -import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java new file mode 100644 index 00000000000..0c61b68fee1 --- /dev/null +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/Util.java @@ -0,0 +1,118 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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.osgi.boot.utils; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Util + * + * Various useful functions used widely. + */ +public class Util +{ + public static final String DEFAULT_DELIMS = ",;"; + + /* ------------------------------------------------------------ */ + /** + * Treating the string as a separated list of filenames, + * convert and return the list of urls. + * + * @param val the separated list + * @param delims the separators (default is ,;) + * @return + * @throws MalformedURLException + */ + public static List fileNamesAsURLs(String val, String delims) + throws Exception + { + String separators = DEFAULT_DELIMS; + if (delims == null) + delims = separators; + + StringTokenizer tokenizer = new StringTokenizer(val, delims, false); + List urls = new ArrayList(); + while (tokenizer.hasMoreTokens()) + { + urls.add(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(new URL(tokenizer.nextToken()))); + } + return urls; + } + + + /* ------------------------------------------------------------ */ + public static void setProperty(Dictionary properties, String key, String value) + { + if (value != null) + { + properties.put(key, value); + } + } + + + /* ------------------------------------------------------------ */ + /** + * recursively substitute the ${sysprop} by their actual system property. + * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no + * sysprop is defined. Not the most efficient code but we are shooting for + * simplicity and speed of development here. + * + * @param value + * @return + */ + public static String resolvePropertyValue(String value) + { + int ind = value.indexOf("${"); + if (ind == -1) { return value; } + int ind2 = value.indexOf('}', ind); + if (ind2 == -1) { return value; } + String sysprop = value.substring(ind + 2, ind2); + String defaultValue = null; + int comma = sysprop.indexOf(','); + if (comma != -1 && comma + 1 != sysprop.length()) + { + defaultValue = sysprop.substring(comma + 1); + defaultValue = resolvePropertyValue(defaultValue); + sysprop = sysprop.substring(0, comma); + } + else + { + defaultValue = "${" + sysprop + "}"; + } + + String v = System.getProperty(sysprop); + + String reminder = value.length() > ind2 + 1 ? value.substring(ind2 + 1) : ""; + reminder = resolvePropertyValue(reminder); + if (v != null) + { + return value.substring(0, ind) + v + reminder; + } + else + { + return value.substring(0, ind) + defaultValue + reminder; + } + } +} diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java index 7349cd08bb6..4eee91bf365 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.osgi.boot.utils.internal; import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URI; @@ -301,25 +302,19 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper * @return a URL to the bundle entry that uses a common protocol */ public URL getLocalURL(URL url) + throws Exception { if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) { - try + + URLConnection conn = url.openConnection(); + conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); + if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) { - URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) - { - BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null); - BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); } - } - catch (Throwable t) - { - System.err.println("Unable to locate the OSGi url: '" + url + "'."); - t.printStackTrace(); + BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null); + BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); } + if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); } } return url; } @@ -335,26 +330,23 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper * @return a URL to the content of the bundle entry that uses the file: * protocol *

+ * @throws IOException */ - public URL getFileURL(URL url) + public URL getFileURL(URL url) throws Exception + { if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) { - try + + URLConnection conn = url.openConnection(); + conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); + if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) { - URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) - { - BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null); - BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); } - } - catch (Throwable t) - { - t.printStackTrace(); + BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null); + BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); } + if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); } + } return url; } diff --git a/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java b/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java index a7f9edeb361..24e4403e918 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java +++ b/jetty-osgi/test-jetty-osgi-webapp/src/main/java/com/acme/osgi/Activator.java @@ -46,11 +46,30 @@ public class Activator implements BundleActivator */ public void start(BundleContext context) throws Exception { + String serverName = "defaultJettyServer"; + + /* Uncomment to create a different server instance to deploy to. Also change + * TestJettyOSGiBootWebAppAsService to use the port 9999 + + Server server = new Server(); + //do any setup on Server in here + serverName = "fooServer"; + Dictionary serverProps = new Hashtable(); + //define the unique name of the server instance + serverProps.put("managedServerName", serverName); + serverProps.put("jetty.port", "9999"); + //let Jetty apply some configuration files to the Server instance + serverProps.put("jetty.etc.config.urls", "file:/opt/jetty/etc/jetty.xml,file:/opt/jetty/etc/jetty-selector.xml,file:/opt/jetty/etc/jetty-deployer.xml"); + //register as an OSGi Service for Jetty to find + context.registerService(Server.class.getName(), server, serverProps); + */ + + //Create a webapp context as a Service and target it at the Server created above WebAppContext webapp = new WebAppContext(); Dictionary props = new Hashtable(); props.put("war","."); props.put("contextPath","/acme"); - //uiProps.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName); + props.put("managedServerName", serverName); context.registerService(ContextHandler.class.getName(),webapp,props); } diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml new file mode 100644 index 00000000000..a6bef16ff1e --- /dev/null +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-https.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http/1.1 + + + + + + + + + + + + + 30000 + + + + diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-selector.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-selector.xml index badf00e976d..67cd87c2a7e 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-selector.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-selector.xml @@ -12,6 +12,15 @@ + + + + + + + + + 300000 diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml new file mode 100644 index 00000000000..b4c3551aadc --- /dev/null +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml @@ -0,0 +1,41 @@ + + + + + + + + + + / + + + / + + + + + SSL_RSA_WITH_DES_CBC_SHA + SSL_DHE_RSA_WITH_DES_CBC_SHA + SSL_DHE_DSS_WITH_DES_CBC_SHA + SSL_RSA_EXPORT_WITH_RC4_40_MD5 + SSL_RSA_EXPORT_WITH_DES40_CBC_SHA + SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA + SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA + + + + + + + + + + + + + + + + + diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml index 7df9ee2d003..4bde8d7222e 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty.xml @@ -14,7 +14,7 @@ - + 10 @@ -44,6 +44,17 @@ + + https + + 32768 + 8192 + 8192 + true + false + 512 + + @@ -57,6 +68,20 @@ + + + + org.eclipse.jetty.webapp.FragmentConfiguration + + + org.eclipse.jetty.plus.webapp.EnvConfiguration + org.eclipse.jetty.plus.webapp.PlusConfiguration + org.eclipse.jetty.annotations.AnnotationConfiguration + + + + + java.naming.factory.initial diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java index ae584ffebd1..2784b202bcb 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootCore.java @@ -62,7 +62,7 @@ public class TestJettyOSGiBootCore } public static List