From: Mathieu Baudier Date: Tue, 11 Dec 2012 09:56:30 +0000 (+0000) Subject: Move Catalina start to runtime X-Git-Tag: argeo-commons-2.1.30~705 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=15d66f3c17c025e40f833a7164aa34fe69ae9fad;p=lgpl%2Fargeo-commons.git Move Catalina start to runtime git-svn-id: https://svn.argeo.org/commons/trunk@5948 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/server/modules/org.argeo.server.catalina.start/.classpath b/server/modules/org.argeo.server.catalina.start/.classpath deleted file mode 100644 index b56882d64..000000000 --- a/server/modules/org.argeo.server.catalina.start/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/server/modules/org.argeo.server.catalina.start/.project b/server/modules/org.argeo.server.catalina.start/.project deleted file mode 100644 index 25f3507c0..000000000 --- a/server/modules/org.argeo.server.catalina.start/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - org.argeo.server.catalina.start - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.pde.PluginNature - - - diff --git a/server/modules/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs b/server/modules/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 6d0bce7d1..000000000 --- a/server/modules/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -#Fri Apr 23 08:40:00 CEST 2010 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/server/modules/org.argeo.server.catalina.start/META-INF/MANIFEST.MF b/server/modules/org.argeo.server.catalina.start/META-INF/MANIFEST.MF deleted file mode 100644 index 2b322c770..000000000 --- a/server/modules/org.argeo.server.catalina.start/META-INF/MANIFEST.MF +++ /dev/null @@ -1,18 +0,0 @@ -Bundle-Activator: org.argeo.dep.osgi.catalina.start.CatalinaActivator -Created-By: Argeo -Import-Package: javax.management;resolution:=optional, - org.apache.catalina, - org.apache.catalina.connector, - org.apache.catalina.core, - org.apache.catalina.startup, - org.apache.catalina.util, - org.apache.commons.io, - org.apache.commons.logging;resolution:=optional, - org.apache.naming.resources, - org.osgi.framework;version="1.3", - org.osgi.service.url;version="1.0" -Bundle-Version: 1.0.0.0009 -Bundle-Name: Tomcat Catalina OSGi Activator (Argeo) -Bundle-Description: Tomcat Catalina OSGi Activator with Argeo addons -Bundle-SymbolicName: org.argeo.dep.osgi.catalina.start -Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/server/modules/org.argeo.server.catalina.start/build.properties b/server/modules/org.argeo.server.catalina.start/build.properties deleted file mode 100644 index 2c65f866b..000000000 --- a/server/modules/org.argeo.server.catalina.start/build.properties +++ /dev/null @@ -1,5 +0,0 @@ -source.. = src/main/java/,\ - src/main/resources/ -output.. = target/classes/ -bin.includes = META-INF/,\ - . diff --git a/server/modules/org.argeo.server.catalina.start/pom.xml b/server/modules/org.argeo.server.catalina.start/pom.xml deleted file mode 100644 index 7a405ebba..000000000 --- a/server/modules/org.argeo.server.catalina.start/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - 4.0.0 - - org.argeo.commons.server - 1.1.9-SNAPSHOT - modules - .. - - org.argeo.server.catalina.start - Commons Catalina starter - Catalina starter hacked from Spring DM sandbox - - - - org.apache.felix - maven-bundle-plugin - - - org.argeo.dep.osgi.catalina.start.CatalinaActivator - - - - - - - - org.eclipse.osgi - org.eclipse.osgi - - - org.argeo.tp - org.apache.catalina - - - org.argeo.tp - org.apache.commons.logging - - - org.argeo.tp - org.apache.commons.io - - - diff --git a/server/modules/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java b/server/modules/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java deleted file mode 100644 index 5c1df1acd..000000000 --- a/server/modules/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.argeo.dep.osgi.catalina.start; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import java.util.Properties; - -import org.apache.commons.io.IOUtils; -import org.osgi.framework.BundleContext; -import org.springframework.osgi.web.tomcat.internal.Activator; - -/** Starts Catalina (hacked from Spring OSGi 1.0) */ -public class CatalinaActivator extends Activator { - private final static String ARGEO_OSGI_DATA_DIR = "argeo.osgi.data.dir"; - - public void start(BundleContext context) throws Exception { - if (!System.getProperties().containsKey(ARGEO_OSGI_DATA_DIR)) { - String osgiInstanceArea = System.getProperty("osgi.instance.area"); - String osgiInstanceAreaDefault = System - .getProperty("osgi.instance.area.default"); - String tempDir = System.getProperty("java.io.tmpdir"); - - File dataDir = null; - if (osgiInstanceArea != null) { - // within OSGi with -data specified - osgiInstanceArea = removeFilePrefix(osgiInstanceArea); - dataDir = new File(osgiInstanceArea); - } else if (osgiInstanceAreaDefault != null) { - // within OSGi without -data specified - osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault); - dataDir = new File(osgiInstanceAreaDefault); - } else {// outside OSGi - dataDir = new File(tempDir + File.separator + "osgiData"); - } - - System.setProperty(ARGEO_OSGI_DATA_DIR, dataDir.getAbsolutePath()); - } - - // Load config properties and put them in system properties so that they - // can be used in tomcat conf - Properties confProps = new Properties(); - URL propsUrl = context.getBundle().getResource("tomcat.properties"); - if (propsUrl != null) { - InputStream in = null; - try { - in = propsUrl.openStream(); - confProps.load(in); - } catch (Exception e) { - throw new RuntimeException("Cannot read catalina properties.", - e); - } finally { - IOUtils.closeQuietly(in); - } - - for (Object key : confProps.keySet()) { - // System properties have priority - if (!System.getProperties().containsKey(key)) { - System.setProperty(key.toString(), - confProps.getProperty(key.toString())); - } - } - } - - // calling Catalina.setCatalinaHome(String) or - // Catalina.setCatalinaBase(String) does the same - if (System.getProperty("catalina.home") == null) - System.setProperty("catalina.home", - System.getProperty(ARGEO_OSGI_DATA_DIR) + "/tomcat"); - if (System.getProperty("catalina.base") == null) - System.setProperty("catalina.base", - System.getProperty(ARGEO_OSGI_DATA_DIR) + "/tomcat"); - - // Call Spring starter - super.start(context); - } - - @Override - public void stop(BundleContext context) throws Exception { - super.stop(context); - } - - protected String removeFilePrefix(String url) { - if (url.startsWith("file:")) - return url.substring("file:".length()); - else if (url.startsWith("reference:file:")) - return url.substring("reference:file:".length()); - else - return url; - } - -} diff --git a/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java b/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java deleted file mode 100644 index 70284fe18..000000000 --- a/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2006-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.osgi.web.tomcat.internal; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.Properties; - -import javax.management.MBeanRegistration; - -import org.apache.catalina.Lifecycle; -import org.apache.catalina.Server; -import org.apache.catalina.Service; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardService; -import org.apache.catalina.util.ServerInfo; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.naming.resources.DirContextURLStreamHandler; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.ServiceRegistration; -import org.osgi.service.url.AbstractURLStreamHandlerService; -import org.osgi.service.url.URLConstants; -import org.osgi.service.url.URLStreamHandlerService; - -/** - * Simple activator for starting Apache Tomcat Catalina container inside OSGi - * using Tomcat's XML configuration files. - * - *

This activator looks initially for a conf/server.xml file - * falling back to conf/default-server.xml. This allows the - * default configuration to be tweaked through fragments for example. - * - * @author Costin Leau - */ -public class Activator implements BundleActivator { - - /** logger */ - private static final Log log = LogFactory.getLog(Activator.class); - - /** default XML configuration */ - private static final String DEFAULT_XML_CONF_LOCATION = "conf/default-server.xml"; - - /** user-configurable XML configuration */ - private static final String XML_CONF_LOCATION = "conf/server.xml"; - - private BundleContext bundleContext; - - private StandardService server; - - private ServiceRegistration registration, urlRegistration; - - private Thread startupThread; - - - public void start(BundleContext context) throws Exception { - this.bundleContext = context; - // do the initialization on a different thread - // so the activator finishes fast - startupThread = new Thread(new Runnable() { - - public void run() { - log.info("Starting " + ServerInfo.getServerInfo() + " ..."); - - // default startup procedure - ClassLoader cl = Activator.class.getClassLoader(); - Thread current = Thread.currentThread(); - ClassLoader old = current.getContextClassLoader(); - - try { - current.setContextClassLoader(cl); - - server = createCatalinaServer(bundleContext.getBundle()); - - server.start(); - - Connector[] connectors = server.findConnectors(); - for (int i = 0; i < connectors.length; i++) { - Connector conn = connectors[i]; - log.info("Succesfully started " + ServerInfo.getServerInfo() + " @ " + conn.getDomain() + ":" - + conn.getPort()); - } - - // register URL service - urlRegistration = registerTomcatJNDIUrlService(); - // publish server as an OSGi service - registration = publishServerAsAService(server); - log.info("Published " + ServerInfo.getServerInfo() + " as an OSGi service"); - } - catch (Exception ex) { - String msg = "Cannot start " + ServerInfo.getServerInfo(); - log.error(msg, ex); - throw new RuntimeException(msg, ex); - } - finally { - current.setContextClassLoader(old); - } - } - }, "Tomcat Catalina Start Thread"); - - startupThread.start(); - } - - public void stop(BundleContext context) throws Exception { - // unpublish service first - registration.unregister(); - urlRegistration.unregister(); - - log.info("Unpublished " + ServerInfo.getServerInfo() + " OSGi service"); - - // default startup procedure - ClassLoader cl = Activator.class.getClassLoader(); - Thread current = Thread.currentThread(); - ClassLoader old = current.getContextClassLoader(); - - try { - current.setContextClassLoader(cl); - //reset CCL - // current.setContextClassLoader(null); - log.info("Stopping " + ServerInfo.getServerInfo() + " ..."); - server.stop(); - log.info("Succesfully stopped " + ServerInfo.getServerInfo()); - } - catch (Exception ex) { - log.error("Cannot stop " + ServerInfo.getServerInfo(), ex); - throw ex; - } - finally { - current.setContextClassLoader(old); - } - } - - private StandardService createCatalinaServer(Bundle bundle) throws Exception { - // first try to use the XML file - URL xmlConfiguration = bundle.getResource(XML_CONF_LOCATION); - - if (xmlConfiguration != null) { - log.info("Using custom XML configuration " + xmlConfiguration); - } - else { - xmlConfiguration = bundle.getResource(DEFAULT_XML_CONF_LOCATION); - if (xmlConfiguration == null) - log.error("No XML configuration found; bailing out..."); - else - log.info("Using default XML configuration " + xmlConfiguration); - } - - return createServerFromXML(xmlConfiguration); - } - - private StandardService createServerFromXML(URL xmlConfiguration) throws IOException { - OsgiCatalina catalina = new OsgiCatalina(); - catalina.setAwait(false); - catalina.setUseShutdownHook(false); - catalina.setName("Catalina"); - catalina.setParentClassLoader(Thread.currentThread().getContextClassLoader()); - - // copy the URL file to a local temporary file (since Catalina doesn't use URL unfortunately) - File configTempFile = File.createTempFile("dm.catalina", ".cfg.xml"); - configTempFile.deleteOnExit(); - - // copy URL to temporary file - copyURLToFile(xmlConfiguration.openStream(), new FileOutputStream(configTempFile)); - log.debug("Copied configuration " + xmlConfiguration + " to temporary file " + configTempFile); - - catalina.setConfigFile(configTempFile.getAbsolutePath()); - - catalina.load(); - - Server server = catalina.getServer(); - - return (StandardService) server.findServices()[0]; - } - - private void copyURLToFile(InputStream inStream, FileOutputStream outStream) { - - int bytesRead; - byte[] buf = new byte[4096]; - try { - while ((bytesRead = inStream.read(buf)) >= 0) { - outStream.write(buf, 0, bytesRead); - } - } - catch (IOException ex) { - throw (RuntimeException) new IllegalStateException("Cannot copy URL to file").initCause(ex); - } - finally { - try { - inStream.close(); - } - catch (IOException ignore) { - } - try { - outStream.close(); - } - catch (IOException ignore) { - } - } - } - - private ServiceRegistration publishServerAsAService(StandardService server) { - Properties props = new Properties(); - // put some extra properties to easily identify the service - props.put(Constants.SERVICE_VENDOR, "Spring Dynamic Modules"); - props.put(Constants.SERVICE_DESCRIPTION, ServerInfo.getServerInfo()); - props.put(Constants.BUNDLE_VERSION, ServerInfo.getServerNumber()); - props.put(Constants.BUNDLE_NAME, bundleContext.getBundle().getSymbolicName()); - - // spring-dm specific property - props.put("org.springframework.osgi.bean.name", "tomcat-server"); - - // publish just the interfaces and the major classes (server/handlerWrapper) - String[] classes = new String[] { StandardService.class.getName(), Service.class.getName(), - MBeanRegistration.class.getName(), Lifecycle.class.getName() }; - - return bundleContext.registerService(classes, server, props); - } - - private ServiceRegistration registerTomcatJNDIUrlService() { - Properties properties = new Properties(); - properties.put(URLConstants.URL_HANDLER_PROTOCOL, "jndi"); - final URLStreamHandler handler = new DirContextURLStreamHandler(); - - return bundleContext.registerService(URLStreamHandlerService.class.getName(), - new AbstractURLStreamHandlerService() { - - private final static String EMPTY_STRING = ""; - - - public URLConnection openConnection(URL u) throws IOException { - return new URL(u, EMPTY_STRING, handler).openConnection(); - } - }, properties); - } -} \ No newline at end of file diff --git a/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java b/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java deleted file mode 100644 index f7903ff6a..000000000 --- a/server/modules/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2006-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.osgi.web.tomcat.internal; - -import org.apache.catalina.Server; -import org.apache.catalina.startup.Catalina; - -/** - * OSGi extension of Catalina class used for easy access to the underlying - * configuration. - * - * @author Costin Leau - * - */ -public class OsgiCatalina extends Catalina { - - public Server getServer() { - return server; - } -} diff --git a/server/modules/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml b/server/modules/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml deleted file mode 100644 index c8cd5bb7b..000000000 --- a/server/modules/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/server/runtime/org.argeo.server.catalina.start/.classpath b/server/runtime/org.argeo.server.catalina.start/.classpath new file mode 100644 index 000000000..b56882d64 --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/server/runtime/org.argeo.server.catalina.start/.project b/server/runtime/org.argeo.server.catalina.start/.project new file mode 100644 index 000000000..25f3507c0 --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/.project @@ -0,0 +1,27 @@ + + + org.argeo.server.catalina.start + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + + diff --git a/server/runtime/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs b/server/runtime/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..6d0bce7d1 --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Fri Apr 23 08:40:00 CEST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/server/runtime/org.argeo.server.catalina.start/META-INF/MANIFEST.MF b/server/runtime/org.argeo.server.catalina.start/META-INF/MANIFEST.MF new file mode 100644 index 000000000..2b322c770 --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Bundle-Activator: org.argeo.dep.osgi.catalina.start.CatalinaActivator +Created-By: Argeo +Import-Package: javax.management;resolution:=optional, + org.apache.catalina, + org.apache.catalina.connector, + org.apache.catalina.core, + org.apache.catalina.startup, + org.apache.catalina.util, + org.apache.commons.io, + org.apache.commons.logging;resolution:=optional, + org.apache.naming.resources, + org.osgi.framework;version="1.3", + org.osgi.service.url;version="1.0" +Bundle-Version: 1.0.0.0009 +Bundle-Name: Tomcat Catalina OSGi Activator (Argeo) +Bundle-Description: Tomcat Catalina OSGi Activator with Argeo addons +Bundle-SymbolicName: org.argeo.dep.osgi.catalina.start +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/server/runtime/org.argeo.server.catalina.start/build.properties b/server/runtime/org.argeo.server.catalina.start/build.properties new file mode 100644 index 000000000..2c65f866b --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/build.properties @@ -0,0 +1,5 @@ +source.. = src/main/java/,\ + src/main/resources/ +output.. = target/classes/ +bin.includes = META-INF/,\ + . diff --git a/server/runtime/org.argeo.server.catalina.start/pom.xml b/server/runtime/org.argeo.server.catalina.start/pom.xml new file mode 100644 index 000000000..7a405ebba --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + org.argeo.commons.server + 1.1.9-SNAPSHOT + modules + .. + + org.argeo.server.catalina.start + Commons Catalina starter + Catalina starter hacked from Spring DM sandbox + + + + org.apache.felix + maven-bundle-plugin + + + org.argeo.dep.osgi.catalina.start.CatalinaActivator + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.argeo.tp + org.apache.catalina + + + org.argeo.tp + org.apache.commons.logging + + + org.argeo.tp + org.apache.commons.io + + + diff --git a/server/runtime/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java new file mode 100644 index 000000000..5c1df1acd --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/argeo/dep/osgi/catalina/start/CatalinaActivator.java @@ -0,0 +1,91 @@ +package org.argeo.dep.osgi.catalina.start; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.util.Properties; + +import org.apache.commons.io.IOUtils; +import org.osgi.framework.BundleContext; +import org.springframework.osgi.web.tomcat.internal.Activator; + +/** Starts Catalina (hacked from Spring OSGi 1.0) */ +public class CatalinaActivator extends Activator { + private final static String ARGEO_OSGI_DATA_DIR = "argeo.osgi.data.dir"; + + public void start(BundleContext context) throws Exception { + if (!System.getProperties().containsKey(ARGEO_OSGI_DATA_DIR)) { + String osgiInstanceArea = System.getProperty("osgi.instance.area"); + String osgiInstanceAreaDefault = System + .getProperty("osgi.instance.area.default"); + String tempDir = System.getProperty("java.io.tmpdir"); + + File dataDir = null; + if (osgiInstanceArea != null) { + // within OSGi with -data specified + osgiInstanceArea = removeFilePrefix(osgiInstanceArea); + dataDir = new File(osgiInstanceArea); + } else if (osgiInstanceAreaDefault != null) { + // within OSGi without -data specified + osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault); + dataDir = new File(osgiInstanceAreaDefault); + } else {// outside OSGi + dataDir = new File(tempDir + File.separator + "osgiData"); + } + + System.setProperty(ARGEO_OSGI_DATA_DIR, dataDir.getAbsolutePath()); + } + + // Load config properties and put them in system properties so that they + // can be used in tomcat conf + Properties confProps = new Properties(); + URL propsUrl = context.getBundle().getResource("tomcat.properties"); + if (propsUrl != null) { + InputStream in = null; + try { + in = propsUrl.openStream(); + confProps.load(in); + } catch (Exception e) { + throw new RuntimeException("Cannot read catalina properties.", + e); + } finally { + IOUtils.closeQuietly(in); + } + + for (Object key : confProps.keySet()) { + // System properties have priority + if (!System.getProperties().containsKey(key)) { + System.setProperty(key.toString(), + confProps.getProperty(key.toString())); + } + } + } + + // calling Catalina.setCatalinaHome(String) or + // Catalina.setCatalinaBase(String) does the same + if (System.getProperty("catalina.home") == null) + System.setProperty("catalina.home", + System.getProperty(ARGEO_OSGI_DATA_DIR) + "/tomcat"); + if (System.getProperty("catalina.base") == null) + System.setProperty("catalina.base", + System.getProperty(ARGEO_OSGI_DATA_DIR) + "/tomcat"); + + // Call Spring starter + super.start(context); + } + + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + } + + protected String removeFilePrefix(String url) { + if (url.startsWith("file:")) + return url.substring("file:".length()); + else if (url.startsWith("reference:file:")) + return url.substring("reference:file:".length()); + else + return url; + } + +} diff --git a/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java new file mode 100644 index 000000000..70284fe18 --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/Activator.java @@ -0,0 +1,257 @@ +/* + * Copyright 2006-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.osgi.web.tomcat.internal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.Properties; + +import javax.management.MBeanRegistration; + +import org.apache.catalina.Lifecycle; +import org.apache.catalina.Server; +import org.apache.catalina.Service; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardService; +import org.apache.catalina.util.ServerInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.naming.resources.DirContextURLStreamHandler; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.url.AbstractURLStreamHandlerService; +import org.osgi.service.url.URLConstants; +import org.osgi.service.url.URLStreamHandlerService; + +/** + * Simple activator for starting Apache Tomcat Catalina container inside OSGi + * using Tomcat's XML configuration files. + * + *

This activator looks initially for a conf/server.xml file + * falling back to conf/default-server.xml. This allows the + * default configuration to be tweaked through fragments for example. + * + * @author Costin Leau + */ +public class Activator implements BundleActivator { + + /** logger */ + private static final Log log = LogFactory.getLog(Activator.class); + + /** default XML configuration */ + private static final String DEFAULT_XML_CONF_LOCATION = "conf/default-server.xml"; + + /** user-configurable XML configuration */ + private static final String XML_CONF_LOCATION = "conf/server.xml"; + + private BundleContext bundleContext; + + private StandardService server; + + private ServiceRegistration registration, urlRegistration; + + private Thread startupThread; + + + public void start(BundleContext context) throws Exception { + this.bundleContext = context; + // do the initialization on a different thread + // so the activator finishes fast + startupThread = new Thread(new Runnable() { + + public void run() { + log.info("Starting " + ServerInfo.getServerInfo() + " ..."); + + // default startup procedure + ClassLoader cl = Activator.class.getClassLoader(); + Thread current = Thread.currentThread(); + ClassLoader old = current.getContextClassLoader(); + + try { + current.setContextClassLoader(cl); + + server = createCatalinaServer(bundleContext.getBundle()); + + server.start(); + + Connector[] connectors = server.findConnectors(); + for (int i = 0; i < connectors.length; i++) { + Connector conn = connectors[i]; + log.info("Succesfully started " + ServerInfo.getServerInfo() + " @ " + conn.getDomain() + ":" + + conn.getPort()); + } + + // register URL service + urlRegistration = registerTomcatJNDIUrlService(); + // publish server as an OSGi service + registration = publishServerAsAService(server); + log.info("Published " + ServerInfo.getServerInfo() + " as an OSGi service"); + } + catch (Exception ex) { + String msg = "Cannot start " + ServerInfo.getServerInfo(); + log.error(msg, ex); + throw new RuntimeException(msg, ex); + } + finally { + current.setContextClassLoader(old); + } + } + }, "Tomcat Catalina Start Thread"); + + startupThread.start(); + } + + public void stop(BundleContext context) throws Exception { + // unpublish service first + registration.unregister(); + urlRegistration.unregister(); + + log.info("Unpublished " + ServerInfo.getServerInfo() + " OSGi service"); + + // default startup procedure + ClassLoader cl = Activator.class.getClassLoader(); + Thread current = Thread.currentThread(); + ClassLoader old = current.getContextClassLoader(); + + try { + current.setContextClassLoader(cl); + //reset CCL + // current.setContextClassLoader(null); + log.info("Stopping " + ServerInfo.getServerInfo() + " ..."); + server.stop(); + log.info("Succesfully stopped " + ServerInfo.getServerInfo()); + } + catch (Exception ex) { + log.error("Cannot stop " + ServerInfo.getServerInfo(), ex); + throw ex; + } + finally { + current.setContextClassLoader(old); + } + } + + private StandardService createCatalinaServer(Bundle bundle) throws Exception { + // first try to use the XML file + URL xmlConfiguration = bundle.getResource(XML_CONF_LOCATION); + + if (xmlConfiguration != null) { + log.info("Using custom XML configuration " + xmlConfiguration); + } + else { + xmlConfiguration = bundle.getResource(DEFAULT_XML_CONF_LOCATION); + if (xmlConfiguration == null) + log.error("No XML configuration found; bailing out..."); + else + log.info("Using default XML configuration " + xmlConfiguration); + } + + return createServerFromXML(xmlConfiguration); + } + + private StandardService createServerFromXML(URL xmlConfiguration) throws IOException { + OsgiCatalina catalina = new OsgiCatalina(); + catalina.setAwait(false); + catalina.setUseShutdownHook(false); + catalina.setName("Catalina"); + catalina.setParentClassLoader(Thread.currentThread().getContextClassLoader()); + + // copy the URL file to a local temporary file (since Catalina doesn't use URL unfortunately) + File configTempFile = File.createTempFile("dm.catalina", ".cfg.xml"); + configTempFile.deleteOnExit(); + + // copy URL to temporary file + copyURLToFile(xmlConfiguration.openStream(), new FileOutputStream(configTempFile)); + log.debug("Copied configuration " + xmlConfiguration + " to temporary file " + configTempFile); + + catalina.setConfigFile(configTempFile.getAbsolutePath()); + + catalina.load(); + + Server server = catalina.getServer(); + + return (StandardService) server.findServices()[0]; + } + + private void copyURLToFile(InputStream inStream, FileOutputStream outStream) { + + int bytesRead; + byte[] buf = new byte[4096]; + try { + while ((bytesRead = inStream.read(buf)) >= 0) { + outStream.write(buf, 0, bytesRead); + } + } + catch (IOException ex) { + throw (RuntimeException) new IllegalStateException("Cannot copy URL to file").initCause(ex); + } + finally { + try { + inStream.close(); + } + catch (IOException ignore) { + } + try { + outStream.close(); + } + catch (IOException ignore) { + } + } + } + + private ServiceRegistration publishServerAsAService(StandardService server) { + Properties props = new Properties(); + // put some extra properties to easily identify the service + props.put(Constants.SERVICE_VENDOR, "Spring Dynamic Modules"); + props.put(Constants.SERVICE_DESCRIPTION, ServerInfo.getServerInfo()); + props.put(Constants.BUNDLE_VERSION, ServerInfo.getServerNumber()); + props.put(Constants.BUNDLE_NAME, bundleContext.getBundle().getSymbolicName()); + + // spring-dm specific property + props.put("org.springframework.osgi.bean.name", "tomcat-server"); + + // publish just the interfaces and the major classes (server/handlerWrapper) + String[] classes = new String[] { StandardService.class.getName(), Service.class.getName(), + MBeanRegistration.class.getName(), Lifecycle.class.getName() }; + + return bundleContext.registerService(classes, server, props); + } + + private ServiceRegistration registerTomcatJNDIUrlService() { + Properties properties = new Properties(); + properties.put(URLConstants.URL_HANDLER_PROTOCOL, "jndi"); + final URLStreamHandler handler = new DirContextURLStreamHandler(); + + return bundleContext.registerService(URLStreamHandlerService.class.getName(), + new AbstractURLStreamHandlerService() { + + private final static String EMPTY_STRING = ""; + + + public URLConnection openConnection(URL u) throws IOException { + return new URL(u, EMPTY_STRING, handler).openConnection(); + } + }, properties); + } +} \ No newline at end of file diff --git a/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java new file mode 100644 index 000000000..f7903ff6a --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/src/main/java/org/springframework/osgi/web/tomcat/internal/OsgiCatalina.java @@ -0,0 +1,34 @@ +/* + * Copyright 2006-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.osgi.web.tomcat.internal; + +import org.apache.catalina.Server; +import org.apache.catalina.startup.Catalina; + +/** + * OSGi extension of Catalina class used for easy access to the underlying + * configuration. + * + * @author Costin Leau + * + */ +public class OsgiCatalina extends Catalina { + + public Server getServer() { + return server; + } +} diff --git a/server/runtime/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml b/server/runtime/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml new file mode 100644 index 000000000..c8cd5bb7b --- /dev/null +++ b/server/runtime/org.argeo.server.catalina.start/src/main/resources/conf/default-server.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + +