001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.tomcat.catalina;
018:
019: import org.apache.catalina.Container;
020: import org.apache.catalina.Engine;
021: import org.apache.catalina.Host;
022: import org.apache.catalina.Lifecycle;
023: import org.apache.catalina.LifecycleEvent;
024: import org.apache.catalina.LifecycleListener;
025: import org.apache.catalina.ServerFactory;
026: import org.apache.catalina.Service;
027: import org.apache.catalina.core.StandardContext;
028: import org.apache.catalina.core.StandardServer;
029: import org.apache.openejb.OpenEJB;
030: import org.apache.openejb.util.Logger;
031: import org.apache.openejb.util.LogCategory;
032: import org.apache.openejb.tomcat.installer.Installer;
033: import org.apache.openejb.tomcat.installer.Paths;
034: import org.apache.openejb.assembler.classic.WebAppBuilder;
035: import org.apache.openejb.core.ServerFederation;
036: import org.apache.openejb.core.ThreadContext;
037: import org.apache.openejb.loader.Loader;
038: import org.apache.openejb.loader.SystemInstance;
039: import org.apache.openejb.server.ServerService;
040: import org.apache.openejb.server.ServiceException;
041: import org.apache.openejb.server.ServiceManager;
042: import org.apache.openejb.server.ejbd.EjbServer;
043: import org.apache.openejb.server.webservices.WsRegistry;
044:
045: import java.io.BufferedInputStream;
046: import java.io.File;
047: import java.io.FileInputStream;
048: import java.io.IOException;
049: import java.io.InputStream;
050: import java.util.Properties;
051:
052: /**
053: * @version $Revision: 617255 $ $Date: 2008-01-31 13:58:36 -0800 (Thu, 31 Jan 2008) $
054: */
055: public class TomcatLoader implements Loader {
056: private EjbServer ejbServer;
057: protected ServiceManager manager;
058:
059: public void init(Properties properties) throws Exception {
060: // Enable System EJBs like the MEJB and DeployerEJB
061: properties.setProperty("openejb.deployments.classpath", "true");
062: properties.setProperty(
063: "openejb.deployments.classpath.filter.systemapps",
064: "false");
065: System.setProperty("openejb.provider.default",
066: "org.apache.openejb.tomcat");
067:
068: // Loader maybe the first thing executed in a new classloader
069: // so we must attempt to initialize the system instance.
070: SystemInstance.init(properties);
071:
072: installConfigFiles(properties);
073:
074: // Not thread safe
075: if (OpenEJB.isInitialized()) {
076: ejbServer = SystemInstance.get().getComponent(
077: EjbServer.class);
078: return;
079: }
080:
081: // Read in and apply the conf/system.properties
082: try {
083: File conf = SystemInstance.get().getBase().getDirectory(
084: "conf");
085: File file = new File(conf, "system.properties");
086: if (file.exists()) {
087: Properties systemProperties = new Properties();
088: FileInputStream fin = new FileInputStream(file);
089: InputStream in = new BufferedInputStream(fin);
090: systemProperties.load(in);
091: System.getProperties().putAll(systemProperties);
092: }
093: } catch (IOException e) {
094: System.out
095: .println("Processing conf/system.properties failed: "
096: + e.getMessage());
097: }
098:
099: System.setProperty("openejb.home", SystemInstance.get()
100: .getHome().getDirectory().getAbsolutePath());
101: System.setProperty("openejb.base", SystemInstance.get()
102: .getBase().getDirectory().getAbsolutePath());
103:
104: // Install tomcat thread context listener
105: ThreadContext
106: .addThreadContextListener(new TomcatThreadContextListener());
107:
108: // Install tomcat war builder
109: TomcatWebAppBuilder tomcatWebAppBuilder = (TomcatWebAppBuilder) SystemInstance
110: .get().getComponent(WebAppBuilder.class);
111: if (tomcatWebAppBuilder == null) {
112: tomcatWebAppBuilder = new TomcatWebAppBuilder();
113: tomcatWebAppBuilder.start();
114: SystemInstance.get().setComponent(WebAppBuilder.class,
115: tomcatWebAppBuilder);
116: }
117:
118: // Install the Tomcat webservice registry
119: TomcatWsRegistry tomcatSoapHandler = (TomcatWsRegistry) SystemInstance
120: .get().getComponent(WsRegistry.class);
121: if (tomcatSoapHandler == null) {
122: tomcatSoapHandler = new TomcatWsRegistry();
123: SystemInstance.get().setComponent(WsRegistry.class,
124: tomcatSoapHandler);
125: }
126:
127: // Start OpenEJB
128: ejbServer = new EjbServer();
129: SystemInstance.get().setComponent(EjbServer.class, ejbServer);
130: OpenEJB.init(properties, new ServerFederation());
131:
132: Properties ejbServerProps = new Properties();
133: ejbServerProps.putAll(properties);
134: ejbServerProps.setProperty("openejb.ejbd.uri",
135: "http://127.0.0.1:8080/openejb/ejb");
136: ejbServer.init(ejbServerProps);
137:
138: // Add our naming context listener to the server which registers all Tomcat resources with OpenEJB
139: StandardServer standardServer = (StandardServer) ServerFactory
140: .getServer();
141: OpenEJBNamingContextListener namingContextListener = new OpenEJBNamingContextListener(
142: standardServer);
143: // Standard server has no state property, so we check global naming context to determine if server is started yet
144: if (standardServer.getGlobalNamingContext() != null) {
145: namingContextListener.start();
146: }
147: standardServer.addLifecycleListener(namingContextListener);
148:
149: // Process all applications already started. This deploys EJBs, PersistenceUnits
150: // and modifies JNDI ENC references to OpenEJB managed objects such as EJBs.
151: processRunningApplications(tomcatWebAppBuilder, standardServer);
152:
153: if (Boolean.getBoolean("openejb.servicemanager.enabled")) {
154: manager = ServiceManager.getManager();
155: manager.init();
156: manager.start(false);
157: } else {
158: try {
159: ServerService serverService = (ServerService) Class
160: .forName(
161: "org.apache.openejb.server.cxf.CxfService")
162: .newInstance();
163: serverService.start();
164: } catch (ClassNotFoundException ignored) {
165: } catch (Exception e) {
166: Logger logger = Logger.getInstance(
167: LogCategory.OPENEJB_STARTUP, getClass());
168: logger.error("Webservices failed to start", e);
169: }
170: }
171:
172: standardServer.addLifecycleListener(new LifecycleListener() {
173: public void lifecycleEvent(LifecycleEvent event) {
174: String type = event.getType();
175: if (Lifecycle.AFTER_STOP_EVENT.equals(type)) {
176: TomcatLoader.this .destroy();
177: }
178: }
179: });
180:
181: Runtime.getRuntime().addShutdownHook(new Thread() {
182: public void run() {
183: TomcatLoader.this .destroy();
184: }
185: });
186: }
187:
188: public void destroy() {
189: if (manager != null) {
190: try {
191: manager.stop();
192: } catch (ServiceException e) {
193: }
194: manager = null;
195: }
196: if (ejbServer != null) {
197: try {
198: ejbServer.stop();
199: } catch (ServiceException e) {
200: }
201: ejbServer = null;
202: }
203: OpenEJB.destroy();
204: }
205:
206: private void installConfigFiles(Properties properties) {
207: String openejbWarDir = properties.getProperty("openejb.war");
208: if (openejbWarDir == null)
209: return;
210:
211: Paths paths = new Paths(new File(openejbWarDir));
212: if (paths.verify()) {
213: Installer installer = new Installer(paths);
214: installer.installConfigFiles();
215: }
216: }
217:
218: private void processRunningApplications(
219: TomcatWebAppBuilder tomcatWebAppBuilder,
220: StandardServer standardServer) {
221: for (Service service : standardServer.findServices()) {
222: if (service.getContainer() instanceof Engine) {
223: Engine engine = (Engine) service.getContainer();
224: for (Container engineChild : engine.findChildren()) {
225: if (engineChild instanceof Host) {
226: Host host = (Host) engineChild;
227: for (Container hostChild : host.findChildren()) {
228: if (hostChild instanceof StandardContext) {
229: StandardContext standardContext = (StandardContext) hostChild;
230: int state = standardContext.getState();
231: if (state == 0) {
232: // context only initialized
233: tomcatWebAppBuilder
234: .init(standardContext);
235: } else if (state == 1) {
236: // context already started
237: standardContext.addParameter(
238: "openejb.start.late",
239: "true");
240: ClassLoader oldCL = Thread
241: .currentThread()
242: .getContextClassLoader();
243: Thread
244: .currentThread()
245: .setContextClassLoader(
246: standardContext
247: .getLoader()
248: .getClassLoader());
249: try {
250: tomcatWebAppBuilder
251: .init(standardContext);
252: tomcatWebAppBuilder
253: .beforeStart(standardContext);
254: tomcatWebAppBuilder
255: .start(standardContext);
256: tomcatWebAppBuilder
257: .afterStart(standardContext);
258: } finally {
259: Thread.currentThread()
260: .setContextClassLoader(
261: oldCL);
262: }
263: standardContext
264: .removeParameter("openejb.start.late");
265: }
266: }
267: }
268: }
269: }
270: }
271: }
272: }
273: }
|