00001
00027 package org.objectweb.jonas.web.jetty50;
00028
00029 import java.io.File;
00030 import java.io.IOException;
00031 import java.net.URL;
00032 import java.net.URLClassLoader;
00033 import java.util.Map;
00034 import java.util.StringTokenizer;
00035 import java.util.Vector;
00036
00037 import javax.management.ObjectName;
00038 import javax.naming.Context;
00039 import javax.naming.NamingException;
00040
00041 import org.objectweb.util.monolog.api.BasicLevel;
00042
00043 import org.objectweb.jonas.jmx.JmxService;
00044 import org.objectweb.jonas.jmx.JonasObjectName;
00045 import org.objectweb.jonas.service.ServiceException;
00046 import org.objectweb.jonas.service.ServiceManager;
00047 import org.objectweb.jonas.web.AbsJWebContainerServiceImpl;
00048 import org.objectweb.jonas.web.JWebContainerServiceException;
00049
00050 import org.mortbay.http.HttpContext;
00051 import org.mortbay.http.HttpListener;
00052 import org.mortbay.jetty.Server;
00053 import org.mortbay.jetty.servlet.WebApplicationContext;
00054
00061 public class JettyJWebContainerServiceImpl extends AbsJWebContainerServiceImpl {
00062
00066 private static final String JETTY_DEFAULT_WEB_XML_FILE = AbsJWebContainerServiceImpl.JONAS_BASE + File.separator + "conf" + File.separator + "jetty5-webdefault.xml";
00067
00071 private static String config = null;
00072
00076 private static final String JETTY_CONFIG = "config";
00077
00081 private Server jettyServer = null;
00082
00088 protected void doInit(javax.naming.Context ctx) throws ServiceException {
00089
00090 super.doInit(ctx);
00091
00092 String strJettyHome = System.getProperty("jetty.home");
00093 if (strJettyHome != null) {
00094 getLogger().log(BasicLevel.DEBUG, "");
00095
00096 try {
00097 config = (String) ctx.lookup(JETTY_CONFIG);
00098 } catch (NamingException neExc) {
00099
00100 String jonasbase = System.getProperties().getProperty("jonas.base");
00101 config = jonasbase + "/conf/jetty5.xml";
00102 }
00103 getLogger().log(BasicLevel.LEVEL_DEBUG, "using configuration file " + config);
00104
00105 jettyServer = new Server();
00106 }
00107
00108 }
00109
00114 public void doStart() throws ServiceException {
00115 getLogger().log(BasicLevel.DEBUG, "");
00116
00117 if (jettyServer != null) {
00118 JmxService srvcJMX = null;
00119
00120
00121 if (config != null) {
00122 try {
00123 jettyServer.configure(config);
00124 jettyServer.start();
00125 } catch (Exception eExc) {
00126 getLogger().log(BasicLevel.LEVEL_ERROR,
00127 "error has occured while starting Jetty server using configuration file " + config, eExc);
00128 }
00129 }
00130
00131 ServiceManager sm = null;
00132 try {
00133 sm = ServiceManager.getInstance();
00134 } catch (Exception e) {
00135 String err = "Cannot get ServiceManager instance.";
00136 getLogger().log(BasicLevel.ERROR, err);
00137 throw new ServiceException(err, e);
00138 }
00139
00140 try {
00141 srvcJMX = (JmxService) sm.getJmxService();
00142 if (srvcJMX != null) {
00143
00144 Object obj;
00145 ObjectName objname;
00146
00147
00148
00149
00150 obj = new JettyJonasServerMBean(jettyServer);
00151 objname = JonasObjectName.wwwService();
00152 srvcJMX.getJmxServer().registerMBean(obj, objname);
00153 }
00154 } catch (ServiceException seExc) {
00155
00156 getLogger().log(
00157 BasicLevel.LEVEL_DEBUG,
00158 "cannot start Jetty server using configuration file " + config
00159 + " using JMX. Will start without JMX.", seExc);
00160 } catch (Exception eExc) {
00161 getLogger().log(BasicLevel.LEVEL_ERROR, "cannot start Jetty server using configuration file " + config,
00162 eExc);
00163 throw new ServiceException("Cannot start Jetty server using configuration file " + config, eExc);
00164 }
00165
00166
00167 super.doStart();
00168 } else {
00169 throw new ServiceException("Cannot start Jetty server.");
00170 }
00171 }
00172
00177 protected void doStop() throws ServiceException {
00178
00179 super.doStop();
00180
00181
00182 getLogger().log(BasicLevel.DEBUG, "");
00183 if (isStarted()) {
00184 JmxService srvcJMX = null;
00185
00186 ServiceManager sm = null;
00187 try {
00188 sm = ServiceManager.getInstance();
00189 } catch (Exception e) {
00190 String err = "Cannot get ServiceManager instance.";
00191 getLogger().log(BasicLevel.ERROR, err);
00192 throw new ServiceException(err, e);
00193 }
00194
00195 try {
00196 srvcJMX = (JmxService) sm.getJmxService();
00197 if (srvcJMX != null) {
00198 ObjectName objname;
00199
00200 objname = new ObjectName("jonas:type=service,name=jetty");
00201 srvcJMX.getJmxServer().unregisterMBean(objname);
00202 jettyServer = null;
00203 objname = new ObjectName("jonas:type=jetty,name=jettylog");
00204 srvcJMX.getJmxServer().unregisterMBean(objname);
00205 objname = new ObjectName("jonas:type=jetty,name=jettycode");
00206 srvcJMX.getJmxServer().unregisterMBean(objname);
00207 }
00208 } catch (ServiceException seExc) {
00209 getLogger().log(BasicLevel.LEVEL_ERROR, "JMX Service not available", seExc);
00210 } catch (Exception eExc) {
00211 getLogger().log(BasicLevel.LEVEL_ERROR, "Cannot stop Jetty server", eExc);
00212 throw new ServiceException("Cannot stop Jetty server", eExc);
00213 }
00214
00215 if (jettyServer != null) {
00216 try {
00217 jettyServer.stop();
00218 jettyServer.destroy();
00219 jettyServer = null;
00220 } catch (Exception eExc) {
00221 getLogger().log(BasicLevel.LEVEL_ERROR,
00222 "error has occured while stopping Jetty server using configuration file " + config, eExc);
00223 }
00224 }
00225 }
00226 }
00227
00236 protected void doRegisterWar(Context ctx) throws JWebContainerServiceException {
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 URL unpackedWarURL = null;
00248 String contextRoot = null;
00249 boolean java2DelegationModel = true;
00250 try {
00251 unpackedWarURL = (URL) ctx.lookup("unpackedWarURL");
00252 contextRoot = (String) ctx.lookup("contextRoot");
00253 Boolean bool = (Boolean) ctx.lookup("java2DelegationModel");
00254 java2DelegationModel = bool.booleanValue();
00255 } catch (NamingException e) {
00256 String err = "Error while getting parameter from context param ";
00257 getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00258 throw new JWebContainerServiceException(err, e);
00259 }
00260
00261 ClassLoader webClassLoader = null;
00262 try {
00263 webClassLoader = (ClassLoader) ctx.lookup("parentCL");
00264 } catch (NamingException e) {
00265 String err = "error while getting parameter from context param ";
00266 getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00267 throw new JWebContainerServiceException(err, e);
00268 }
00269
00270 String hostName = null;
00271 try {
00272 hostName = (String) ctx.lookup("hostName");
00273 } catch (NamingException e) {
00274 hostName = "";
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284 if (contextRoot.equals("/")) {
00285 contextRoot = "";
00286 } else if (contextRoot.equalsIgnoreCase("ROOT")) {
00287
00288 contextRoot = "";
00289 }
00290
00291
00292 File fWar = new File(unpackedWarURL.getFile());
00293 String fileName = fWar.getAbsolutePath();
00294
00295 if (jettyServer != null) {
00296 try {
00297 WebApplicationContext contextWebApp;
00298
00299 if ((hostName == null) || (hostName.length() == 0)) {
00300
00301 getLogger().log(BasicLevel.DEBUG,
00302 "Jetty server installing web app " + fileName + " and context " + contextRoot);
00303 contextWebApp = jettyServer.addWebApplication(contextRoot, fileName);
00304 } else {
00305
00306 getLogger().log(
00307 BasicLevel.DEBUG,
00308 "Jetty server installing web app " + fileName + " on host " + hostName + " and context "
00309 + contextRoot);
00310 contextWebApp = jettyServer.addWebApplication(hostName, contextRoot, fileName);
00311 }
00312
00313
00314 if (new File(JETTY_DEFAULT_WEB_XML_FILE).exists()) {
00315 contextWebApp.setDefaultsDescriptor(JETTY_DEFAULT_WEB_XML_FILE);
00316 } else {
00317 getLogger().log(BasicLevel.WARN, "The file '" + JETTY_DEFAULT_WEB_XML_FILE + "' is not present. Check that your JONAS_BASE is up-to-date.");
00318 }
00319
00320
00321 contextWebApp.setAttribute("org.apache.catalina.jsp_classpath", getJOnASClassPath(webClassLoader));
00322
00323
00324 contextWebApp.setParentClassLoader(webClassLoader);
00325
00326
00327 contextWebApp.setClassLoaderJava2Compliant(java2DelegationModel);
00328
00329 getLogger().log(BasicLevel.DEBUG,
00330 "Webapp class loader java 2 delegation model set to " + java2DelegationModel);
00331
00332 getLogger().log(BasicLevel.DEBUG, "Jetty server starting web app " + fileName);
00333 contextWebApp.start();
00334 getLogger().log(BasicLevel.DEBUG, "Jetty server is running web app " + fileName);
00335
00336 } catch (IOException ioeExc) {
00337 String err = "Cannot install this web application " + ioeExc;
00338 getLogger().log(BasicLevel.ERROR, err);
00339 throw new JWebContainerServiceException(err, ioeExc);
00340 } catch (Exception eExc) {
00341 String err = "Cannot start this web application " + eExc;
00342 getLogger().log(BasicLevel.ERROR, err);
00343 throw new JWebContainerServiceException(err, eExc);
00344 }
00345 } else {
00346 getLogger().log(BasicLevel.DEBUG, "No Jetty server to install web app " + fileName);
00347 }
00348 }
00349
00356 public String getJOnASClassPath(ClassLoader webClassLoader) {
00357
00358 StringBuffer classpath = new StringBuffer();
00359 int n = 0;
00360 while (webClassLoader != null) {
00361 if (!(webClassLoader instanceof URLClassLoader)) {
00362 break;
00363 }
00364 URL[] repositories = ((URLClassLoader) webClassLoader).getURLs();
00365 for (int i = 0; i < repositories.length; i++) {
00366 String repository = repositories[i].toString();
00367 if (repository.startsWith("file://")) {
00368 repository = repository.substring("file://".length());
00369 } else if (repository.startsWith("file:")) {
00370 repository = repository.substring("file:".length());
00371 } else {
00372 continue;
00373 }
00374 if (repository == null) {
00375 continue;
00376 }
00377 if (n > 0) {
00378 classpath.append(File.pathSeparator);
00379 }
00380 classpath.append(repository);
00381 n++;
00382 }
00383 webClassLoader = webClassLoader.getParent();
00384 }
00385
00386 return classpath.toString();
00387 }
00388
00395 protected void doUnRegisterWar(Context ctx) throws JWebContainerServiceException {
00396
00397
00398
00399 String contextRoot = null;
00400 try {
00401 contextRoot = (String) ctx.lookup("contextRoot");
00402 } catch (NamingException e) {
00403 String err = "Error while getting parameter from context param ";
00404 getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00405 throw new JWebContainerServiceException(err, e);
00406 }
00407
00408 String hostName = null;
00409 try {
00410 hostName = (String) ctx.lookup("hostName");
00411 } catch (NamingException e) {
00412 hostName = "";
00413 }
00414
00415
00416
00417
00418 if (contextRoot.equals("/")) {
00419 contextRoot = "";
00420 } else if (contextRoot.equalsIgnoreCase("ROOT")) {
00421
00422 contextRoot = "";
00423 }
00424
00425 if (jettyServer != null) {
00426 HttpContext contextWebApp;
00427
00428 if ((hostName == null) || (hostName.length() == 0)) {
00429
00430 getLogger().log(BasicLevel.DEBUG, "Jetty server looking upweb app " + " from context " + contextRoot);
00431 contextWebApp = jettyServer.getContext(contextRoot);
00432 } else {
00433
00434 getLogger().log(BasicLevel.DEBUG,
00435 "Jetty server looking up web app " + " on host " + hostName + " and context " + contextRoot);
00436 contextWebApp = jettyServer.getContext(hostName, contextRoot);
00437 }
00438
00439 if (contextWebApp != null) {
00440 getLogger().log(BasicLevel.DEBUG,
00441 "Jetty server found and is stopping web app at context " + contextRoot);
00442
00443
00444 try {
00445 contextWebApp.stop(true);
00446 } catch (InterruptedException ieExc) {
00447 getLogger().log(BasicLevel.LEVEL_DEBUG,
00448 "Jetty server encoutered exception while stopping web application ", ieExc);
00449 }
00450
00451 getLogger().log(BasicLevel.DEBUG,
00452 "Jetty server stopped and is removing web app at context " + contextRoot);
00453
00454 jettyServer.removeContext(contextWebApp);
00455
00456 getLogger().log(BasicLevel.DEBUG,
00457 "Jetty server removed and is destroying web app at context " + contextRoot);
00458
00459 contextWebApp.destroy();
00460
00461 getLogger().log(BasicLevel.DEBUG, "Jetty server unloaded web app at context " + contextRoot);
00462
00463 } else {
00464 getLogger().log(BasicLevel.DEBUG, "Jetty server didn't find web app at context " + contextRoot);
00465 }
00466
00467 } else {
00468 getLogger().log(BasicLevel.DEBUG, "No Jetty server to install web app at context " + contextRoot);
00469 }
00470 }
00471
00475 protected void updateServerInfos() {
00476 String infos = org.mortbay.http.Version.getImplVersion();
00477
00478 StringTokenizer st = new StringTokenizer(infos, "/");
00479 if (st.countTokens() != 2) {
00480 setServerName(infos);
00481 setServerVersion("");
00482 } else {
00483 setServerName(st.nextToken());
00484 setServerVersion(st.nextToken());
00485 }
00486 }
00487
00494 public String getDefaultHost() throws JWebContainerServiceException {
00495 Map hosts = jettyServer.getHostMap();
00496
00497 if (hosts.size() != 1) {
00498 String err = "Cannot determine default host :" + " Jetty server has more than 1 host";
00499 throw new JWebContainerServiceException(err);
00500 }
00501 String vHost = (String) hosts.keySet().iterator().next();
00502 if (vHost == null) {
00503 return "localhost";
00504 } else {
00505 return vHost;
00506 }
00507 }
00508
00516 public String getDefaultHttpPort() throws JWebContainerServiceException {
00517 HttpListener[] listeners = jettyServer.getListeners();
00518 Vector http = new Vector();
00519 for (int i = 0; i < listeners.length; i++) {
00520 String scheme = listeners[i].getDefaultScheme();
00521 if (scheme.equalsIgnoreCase("http")) {
00522 http.add(listeners[i]);
00523 }
00524 }
00525
00526 if (http.size() != 1) {
00527 String err = "Cannot determine default http port :" + " Jetty server has more (or zero) HTTP Listener";
00528 throw new JWebContainerServiceException(err);
00529 }
00530
00531 return new String("" + ((HttpListener) http.get(0)).getPort());
00532 }
00533
00541 public String getDefaultHttpsPort() throws JWebContainerServiceException {
00542 HttpListener[] listeners = jettyServer.getListeners();
00543 Vector http = new Vector();
00544 for (int i = 0; i < listeners.length; i++) {
00545 String scheme = listeners[i].getDefaultScheme();
00546 if (scheme.equalsIgnoreCase("https")) {
00547 http.add(listeners[i]);
00548 }
00549 }
00550
00551 if (http.size() != 1) {
00552 String err = "Cannot determine default http port :" + " Jetty server has more (or zero) HTTPS Listener";
00553 throw new JWebContainerServiceException(err);
00554 }
00555
00556 return new String("" + ((HttpListener) http.get(0)).getPort());
00557 }
00558
00559 }
00560