1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.catalina.startup;
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.InetAddress;
25 import java.util.HashMap;
26
27 import org.apache.catalina.Authenticator;
28 import org.apache.catalina.Container;
29 import org.apache.catalina.Context;
30 import org.apache.catalina.Engine;
31 import org.apache.catalina.Host;
32 import org.apache.catalina.Lifecycle;
33 import org.apache.catalina.LifecycleException;
34 import org.apache.catalina.LifecycleListener;
35 import org.apache.catalina.Loader;
36 import org.apache.catalina.Realm;
37 import org.apache.catalina.Valve;
38 import org.apache.catalina.connector.Connector;
39 import org.apache.catalina.core.StandardContext;
40 import org.apache.catalina.core.StandardEngine;
41 import org.apache.catalina.core.StandardHost;
42 import org.apache.catalina.core.StandardService;
43 import org.apache.catalina.loader.WebappLoader;
44 import org.apache.catalina.security.SecurityConfig;
45 import org.apache.catalina.util.LifecycleSupport;
46 import org.apache.catalina.util.StringManager;
47 import org.apache.juli.logging.Log;
48 import org.apache.juli.logging.LogFactory;
49 import org.apache.tomcat.util.IntrospectionUtils;
50 import org.apache.tomcat.util.log.SystemLogHandler;
51
52
53 /**
54 * Convenience class to embed a Catalina servlet container environment
55 * inside another application. You must call the methods of this class in the
56 * following order to ensure correct operation.
57 *
58 * <ul>
59 * <li>Instantiate a new instance of this class.</li>
60 * <li>Set the relevant properties of this object itself. In particular,
61 * you will want to establish the default Logger to be used, as well
62 * as the default Realm if you are using container-managed security.</li>
63 * <li>Call <code>createEngine()</code> to create an Engine object, and then
64 * call its property setters as desired.</li>
65 * <li>Call <code>createHost()</code> to create at least one virtual Host
66 * associated with the newly created Engine, and then call its property
67 * setters as desired. After you customize this Host, add it to the
68 * corresponding Engine with <code>engine.addChild(host)</code>.</li>
69 * <li>Call <code>createContext()</code> to create at least one Context
70 * associated with each newly created Host, and then call its property
71 * setters as desired. You <strong>SHOULD</strong> create a Context with
72 * a pathname equal to a zero-length string, which will be used to process
73 * all requests not mapped to some other Context. After you customize
74 * this Context, add it to the corresponding Host with
75 * <code>host.addChild(context)</code>.</li>
76 * <li>Call <code>addEngine()</code> to attach this Engine to the set of
77 * defined Engines for this object.</li>
78 * <li>Call <code>createConnector()</code> to create at least one TCP/IP
79 * connector, and then call its property setters as desired.</li>
80 * <li>Call <code>addConnector()</code> to attach this Connector to the set
81 * of defined Connectors for this object. The added Connector will use
82 * the most recently added Engine to process its received requests.</li>
83 * <li>Repeat the above series of steps as often as required (although there
84 * will typically be only one Engine instance created).</li>
85 * <li>Call <code>start()</code> to initiate normal operations of all the
86 * attached components.</li>
87 * </ul>
88 *
89 * After normal operations have begun, you can add and remove Connectors,
90 * Engines, Hosts, and Contexts on the fly. However, once you have removed
91 * a particular component, it must be thrown away -- you can create a new one
92 * with the same characteristics if you merely want to do a restart.
93 * <p>
94 * To initiate a normal shutdown, call the <code>stop()</code> method of
95 * this object.
96 * <p>
97 * @see org.apache.catalina.startup.Catalina#main For a complete example
98 * of how Tomcat is set up and launched as an Embedded application.
99 *
100 * @author Craig R. McClanahan
101 * @version $Revision: 586738 $ $Date: 2007-10-20 16:57:18 +0200 (sam., 20 oct. 2007) $
102 */
103
104 public class Embedded extends StandardService implements Lifecycle {
105 private static Log log = LogFactory.getLog(Embedded.class);
106
107 // ----------------------------------------------------------- Constructors
108
109
110 /**
111 * Construct a new instance of this class with default properties.
112 */
113 public Embedded() {
114
115 this(null);
116
117 }
118
119
120 /**
121 * Construct a new instance of this class with specified properties.
122 *
123 * @param realm Realm implementation to be inherited by all components
124 * (unless overridden further down the container hierarchy)
125 */
126 public Embedded(Realm realm) {
127
128 super();
129 setRealm(realm);
130 setSecurityProtection();
131
132 }
133
134
135 // ----------------------------------------------------- Instance Variables
136
137
138 /**
139 * Is naming enabled ?
140 */
141 protected boolean useNaming = true;
142
143
144 /**
145 * Is standard streams redirection enabled ?
146 */
147 protected boolean redirectStreams = true;
148
149
150 /**
151 * The set of Engines that have been deployed in this server. Normally
152 * there will only be one.
153 */
154 protected Engine engines[] = new Engine[0];
155
156
157 /**
158 * Custom mappings of login methods to authenticators
159 */
160 protected HashMap authenticators;
161
162
163 /**
164 * Descriptive information about this server implementation.
165 */
166 protected static final String info =
167 "org.apache.catalina.startup.Embedded/1.0";
168
169
170 /**
171 * The lifecycle event support for this component.
172 */
173 protected LifecycleSupport lifecycle = new LifecycleSupport(this);
174
175
176 /**
177 * The default realm to be used by all containers associated with
178 * this compoennt.
179 */
180 protected Realm realm = null;
181
182
183 /**
184 * The string manager for this package.
185 */
186 protected static StringManager sm =
187 StringManager.getManager(Constants.Package);
188
189
190 /**
191 * Has this component been started yet?
192 */
193 protected boolean started = false;
194
195 /**
196 * Use await.
197 */
198 protected boolean await = false;
199
200
201 // ------------------------------------------------------------- Properties
202
203
204 /**
205 * Return true if naming is enabled.
206 */
207 public boolean isUseNaming() {
208
209 return (this.useNaming);
210
211 }
212
213
214 /**
215 * Enables or disables naming support.
216 *
217 * @param useNaming The new use naming value
218 */
219 public void setUseNaming(boolean useNaming) {
220
221 boolean oldUseNaming = this.useNaming;
222 this.useNaming = useNaming;
223 support.firePropertyChange("useNaming", new Boolean(oldUseNaming),
224 new Boolean(this.useNaming));
225
226 }
227
228
229 /**
230 * Return true if redirction of standard streams is enabled.
231 */
232 public boolean isRedirectStreams() {
233
234 return (this.redirectStreams);
235
236 }
237
238
239 /**
240 * Enables or disables naming support.
241 *
242 * @param useNaming The new use naming value
243 */
244 public void setRedirectStreams(boolean redirectStreams) {
245
246 boolean oldRedirectStreams = this.redirectStreams;
247 this.redirectStreams = redirectStreams;
248 support.firePropertyChange("redirectStreams", new Boolean(oldRedirectStreams),
249 new Boolean(this.redirectStreams));
250
251 }
252
253
254 /**
255 * Return the default Realm for our Containers.
256 */
257 public Realm getRealm() {
258
259 return (this.realm);
260
261 }
262
263
264 /**
265 * Set the default Realm for our Containers.
266 *
267 * @param realm The new default realm
268 */
269 public void setRealm(Realm realm) {
270
271 Realm oldRealm = this.realm;
272 this.realm = realm;
273 support.firePropertyChange("realm", oldRealm, this.realm);
274
275 }
276
277 public void setAwait(boolean b) {
278 await = b;
279 }
280
281 public boolean isAwait() {
282 return await;
283 }
284
285 public void setCatalinaHome( String s ) {
286 System.setProperty( "catalina.home", s);
287 }
288
289 public void setCatalinaBase( String s ) {
290 System.setProperty( "catalina.base", s);
291 }
292
293 public String getCatalinaHome() {
294 return System.getProperty("catalina.home");
295 }
296
297 public String getCatalinaBase() {
298 return System.getProperty("catalina.base");
299 }
300
301
302 // --------------------------------------------------------- Public Methods
303
304 /**
305 * Add a new Connector to the set of defined Connectors. The newly
306 * added Connector will be associated with the most recently added Engine.
307 *
308 * @param connector The connector to be added
309 *
310 * @exception IllegalStateException if no engines have been added yet
311 */
312 public synchronized void addConnector(Connector connector) {
313
314 if( log.isDebugEnabled() ) {
315 log.debug("Adding connector (" + connector.getInfo() + ")");
316 }
317
318 // Make sure we have a Container to send requests to
319 if (engines.length < 1)
320 throw new IllegalStateException
321 (sm.getString("embedded.noEngines"));
322
323 /*
324 * Add the connector. This will set the connector's container to the
325 * most recently added Engine
326 */
327 super.addConnector(connector);
328 }
329
330
331 /**
332 * Add a new Engine to the set of defined Engines.
333 *
334 * @param engine The engine to be added
335 */
336 public synchronized void addEngine(Engine engine) {
337
338 if( log.isDebugEnabled() )
339 log.debug("Adding engine (" + engine.getInfo() + ")");
340
341 // Add this Engine to our set of defined Engines
342 Engine results[] = new Engine[engines.length + 1];
343 for (int i = 0; i < engines.length; i++)
344 results[i] = engines[i];
345 results[engines.length] = engine;
346 engines = results;
347
348 // Start this Engine if necessary
349 if (started && (engine instanceof Lifecycle)) {
350 try {
351 ((Lifecycle) engine).start();
352 } catch (LifecycleException e) {
353 log.error("Engine.start", e);
354 }
355 }
356
357 this.container = engine;
358 }
359
360
361 /**
362 * Create, configure, and return a new TCP/IP socket connector
363 * based on the specified properties.
364 *
365 * @param address InetAddress to bind to, or <code>null</code> if the
366 * connector is supposed to bind to all addresses on this server
367 * @param port Port number to listen to
368 * @param secure true if the generated connector is supposed to be
369 * SSL-enabled, and false otherwise
370 */
371 public Connector createConnector(InetAddress address, int port,
372 boolean secure) {
373 return createConnector(address != null? address.toString() : null,
374 port, secure);
375 }
376
377 public Connector createConnector(String address, int port,
378 boolean secure) {
379 String protocol = "http";
380 if (secure) {
381 protocol = "https";
382 }
383
384 return createConnector(address, port, protocol);
385 }
386
387
388 public Connector createConnector(InetAddress address, int port,
389 String protocol) {
390 return createConnector(address != null? address.toString() : null,
391 port, protocol);
392 }
393
394 public Connector createConnector(String address, int port,
395 String protocol) {
396
397 Connector connector = null;
398
399 if (address != null) {
400 /*
401 * InetAddress.toString() returns a string of the form
402 * "<hostname>/<literal_IP>". Get the latter part, so that the
403 * address can be parsed (back) into an InetAddress using
404 * InetAddress.getByName().
405 */
406 int index = address.indexOf('/');
407 if (index != -1) {
408 address = address.substring(index + 1);
409 }
410 }
411
412 if (log.isDebugEnabled()) {
413 log.debug("Creating connector for address='" +
414 ((address == null) ? "ALL" : address) +
415 "' port='" + port + "' protocol='" + protocol + "'");
416 }
417
418 try {
419
420 if (protocol.equals("ajp")) {
421 connector = new Connector("org.apache.jk.server.JkCoyoteHandler");
422 } else if (protocol.equals("memory")) {
423 connector = new Connector("org.apache.coyote.memory.MemoryProtocolHandler");
424 } else if (protocol.equals("http")) {
425 connector = new Connector();
426 } else if (protocol.equals("https")) {
427 connector = new Connector();
428 connector.setScheme("https");
429 connector.setSecure(true);
430 connector.setProperty("SSLEnabled","true");
431 // FIXME !!!! SET SSL PROPERTIES
432 } else {
433 connector = new Connector(protocol);
434 }
435
436 if (address != null) {
437 IntrospectionUtils.setProperty(connector, "address",
438 "" + address);
439 }
440 IntrospectionUtils.setProperty(connector, "port", "" + port);
441
442 } catch (Exception e) {
443 log.error("Couldn't create connector.");
444 }
445
446 return (connector);
447
448 }
449
450 /**
451 * Create, configure, and return a Context that will process all
452 * HTTP requests received from one of the associated Connectors,
453 * and directed to the specified context path on the virtual host
454 * to which this Context is connected.
455 * <p>
456 * After you have customized the properties, listeners, and Valves
457 * for this Context, you must attach it to the corresponding Host
458 * by calling:
459 * <pre>
460 * host.addChild(context);
461 * </pre>
462 * which will also cause the Context to be started if the Host has
463 * already been started.
464 *
465 * @param path Context path of this application ("" for the default
466 * application for this host, must start with a slash otherwise)
467 * @param docBase Absolute pathname to the document base directory
468 * for this web application
469 *
470 * @exception IllegalArgumentException if an invalid parameter
471 * is specified
472 */
473 public Context createContext(String path, String docBase) {
474
475 if( log.isDebugEnabled() )
476 log.debug("Creating context '" + path + "' with docBase '" +
477 docBase + "'");
478
479 StandardContext context = new StandardContext();
480
481 context.setDocBase(docBase);
482 context.setPath(path);
483
484 ContextConfig config = new ContextConfig();
485 config.setCustomAuthenticators(authenticators);
486 ((Lifecycle) context).addLifecycleListener(config);
487
488 return (context);
489
490 }
491
492
493 /**
494 * Create, configure, and return an Engine that will process all
495 * HTTP requests received from one of the associated Connectors,
496 * based on the specified properties.
497 */
498 public Engine createEngine() {
499
500 if( log.isDebugEnabled() )
501 log.debug("Creating engine");
502
503 StandardEngine engine = new StandardEngine();
504
505 // Default host will be set to the first host added
506 engine.setRealm(realm); // Inherited by all children
507
508 return (engine);
509
510 }
511
512
513 /**
514 * Create, configure, and return a Host that will process all
515 * HTTP requests received from one of the associated Connectors,
516 * and directed to the specified virtual host.
517 * <p>
518 * After you have customized the properties, listeners, and Valves
519 * for this Host, you must attach it to the corresponding Engine
520 * by calling:
521 * <pre>
522 * engine.addChild(host);
523 * </pre>
524 * which will also cause the Host to be started if the Engine has
525 * already been started. If this is the default (or only) Host you
526 * will be defining, you may also tell the Engine to pass all requests
527 * not assigned to another virtual host to this one:
528 * <pre>
529 * engine.setDefaultHost(host.getName());
530 * </pre>
531 *
532 * @param name Canonical name of this virtual host
533 * @param appBase Absolute pathname to the application base directory
534 * for this virtual host
535 *
536 * @exception IllegalArgumentException if an invalid parameter
537 * is specified
538 */
539 public Host createHost(String name, String appBase) {
540
541 if( log.isDebugEnabled() )
542 log.debug("Creating host '" + name + "' with appBase '" +
543 appBase + "'");
544
545 StandardHost host = new StandardHost();
546
547 host.setAppBase(appBase);
548 host.setName(name);
549
550 return (host);
551
552 }
553
554
555 /**
556 * Create and return a class loader manager that can be customized, and
557 * then attached to a Context, before it is started.
558 *
559 * @param parent ClassLoader that will be the parent of the one
560 * created by this Loader
561 */
562 public Loader createLoader(ClassLoader parent) {
563
564 if( log.isDebugEnabled() )
565 log.debug("Creating Loader with parent class loader '" +
566 parent + "'");
567
568 WebappLoader loader = new WebappLoader(parent);
569 return (loader);
570
571 }
572
573
574 /**
575 * Return descriptive information about this Server implementation and
576 * the corresponding version number, in the format
577 * <code><description>/<version></code>.
578 */
579 public String getInfo() {
580
581 return (info);
582
583 }
584
585
586 /**
587 * Remove the specified Context from the set of defined Contexts for its
588 * associated Host. If this is the last Context for this Host, the Host
589 * will also be removed.
590 *
591 * @param context The Context to be removed
592 */
593 public synchronized void removeContext(Context context) {
594
595 if( log.isDebugEnabled() )
596 log.debug("Removing context[" + context.getPath() + "]");
597
598 // Is this Context actually among those that are defined?
599 boolean found = false;
600 for (int i = 0; i < engines.length; i++) {
601 Container hosts[] = engines[i].findChildren();
602 for (int j = 0; j < hosts.length; j++) {
603 Container contexts[] = hosts[j].findChildren();
604 for (int k = 0; k < contexts.length; k++) {
605 if (context == (Context) contexts[k]) {
606 found = true;
607 break;
608 }
609 }
610 if (found)
611 break;
612 }
613 if (found)
614 break;
615 }
616 if (!found)
617 return;
618
619 // Remove this Context from the associated Host
620 if( log.isDebugEnabled() )
621 log.debug(" Removing this Context");
622 context.getParent().removeChild(context);
623
624 }
625
626
627 /**
628 * Remove the specified Engine from the set of defined Engines, along with
629 * all of its related Hosts and Contexts. All associated Connectors are
630 * also removed.
631 *
632 * @param engine The Engine to be removed
633 */
634 public synchronized void removeEngine(Engine engine) {
635
636 if( log.isDebugEnabled() )
637 log.debug("Removing engine (" + engine.getInfo() + ")");
638
639 // Is the specified Engine actually defined?
640 int j = -1;
641 for (int i = 0; i < engines.length; i++) {
642 if (engine == engines[i]) {
643 j = i;
644 break;
645 }
646 }
647 if (j < 0)
648 return;
649
650 // Remove any Connector that is using this Engine
651 if( log.isDebugEnabled() )
652 log.debug(" Removing related Containers");
653 while (true) {
654 int n = -1;
655 for (int i = 0; i < connectors.length; i++) {
656 if (connectors[i].getContainer() == (Container) engine) {
657 n = i;
658 break;
659 }
660 }
661 if (n < 0)
662 break;
663 removeConnector(connectors[n]);
664 }
665
666 // Stop this Engine if necessary
667 if (engine instanceof Lifecycle) {
668 if( log.isDebugEnabled() )
669 log.debug(" Stopping this Engine");
670 try {
671 ((Lifecycle) engine).stop();
672 } catch (LifecycleException e) {
673 log.error("Engine.stop", e);
674 }
675 }
676
677 // Remove this Engine from our set of defined Engines
678 if( log.isDebugEnabled() )
679 log.debug(" Removing this Engine");
680 int k = 0;
681 Engine results[] = new Engine[engines.length - 1];
682 for (int i = 0; i < engines.length; i++) {
683 if (i != j)
684 results[k++] = engines[i];
685 }
686 engines = results;
687
688 }
689
690
691 /**
692 * Remove the specified Host, along with all of its related Contexts,
693 * from the set of defined Hosts for its associated Engine. If this is
694 * the last Host for this Engine, the Engine will also be removed.
695 *
696 * @param host The Host to be removed
697 */
698 public synchronized void removeHost(Host host) {
699
700 if( log.isDebugEnabled() )
701 log.debug("Removing host[" + host.getName() + "]");
702
703 // Is this Host actually among those that are defined?
704 boolean found = false;
705 for (int i = 0; i < engines.length; i++) {
706 Container hosts[] = engines[i].findChildren();
707 for (int j = 0; j < hosts.length; j++) {
708 if (host == (Host) hosts[j]) {
709 found = true;
710 break;
711
712 }
713 }
714 if (found)
715 break;
716 }
717 if (!found)
718 return;
719
720 // Remove this Host from the associated Engine
721 if( log.isDebugEnabled() )
722 log.debug(" Removing this Host");
723 host.getParent().removeChild(host);
724
725 }
726
727
728 /*
729 * Maps the specified login method to the specified authenticator, allowing
730 * the mappings in org/apache/catalina/startup/Authenticators.properties
731 * to be overridden.
732 *
733 * @param authenticator Authenticator to handle authentication for the
734 * specified login method
735 * @param loginMethod Login method that maps to the specified authenticator
736 *
737 * @throws IllegalArgumentException if the specified authenticator does not
738 * implement the org.apache.catalina.Valve interface
739 */
740 public void addAuthenticator(Authenticator authenticator,
741 String loginMethod) {
742 if (!(authenticator instanceof Valve)) {
743 throw new IllegalArgumentException(
744 sm.getString("embedded.authenticatorNotInstanceOfValve"));
745 }
746 if (authenticators == null) {
747 synchronized (this) {
748 if (authenticators == null) {
749 authenticators = new HashMap();
750 }
751 }
752 }
753 authenticators.put(loginMethod, authenticator);
754 }
755
756
757 // ------------------------------------------------------ Lifecycle Methods
758
759
760 /**
761 * Add a lifecycle event listener to this component.
762 *
763 * @param listener The listener to add
764 */
765 public void addLifecycleListener(LifecycleListener listener) {
766
767 lifecycle.addLifecycleListener(listener);
768
769 }
770
771
772 /**
773 * Get the lifecycle listeners associated with this lifecycle. If this
774 * Lifecycle has no listeners registered, a zero-length array is returned.
775 */
776 public LifecycleListener[] findLifecycleListeners() {
777
778 return lifecycle.findLifecycleListeners();
779
780 }
781
782
783 /**
784 * Remove a lifecycle event listener from this component.
785 *
786 * @param listener The listener to remove
787 */
788 public void removeLifecycleListener(LifecycleListener listener) {
789
790 lifecycle.removeLifecycleListener(listener);
791
792 }
793
794
795 /**
796 * Prepare for the beginning of active use of the public methods of this
797 * component. This method should be called after <code>configure()</code>,
798 * and before any of the public methods of the component are utilized.
799 *
800 * @exception LifecycleException if this component detects a fatal error
801 * that prevents this component from being used
802 */
803 public void start() throws LifecycleException {
804
805 if( log.isInfoEnabled() )
806 log.info("Starting tomcat server");
807
808 // Validate the setup of our required system properties
809 initDirs();
810
811 // Initialize some naming specific properties
812 initNaming();
813
814 // Validate and update our current component state
815 if (started)
816 throw new LifecycleException
817 (sm.getString("embedded.alreadyStarted"));
818 lifecycle.fireLifecycleEvent(START_EVENT, null);
819 started = true;
820 initialized = true;
821
822 // Start our defined Engines first
823 for (int i = 0; i < engines.length; i++) {
824 if (engines[i] instanceof Lifecycle)
825 ((Lifecycle) engines[i]).start();
826 }
827
828 // Start our defined Connectors second
829 for (int i = 0; i < connectors.length; i++) {
830 connectors[i].initialize();
831 if (connectors[i] instanceof Lifecycle)
832 ((Lifecycle) connectors[i]).start();
833 }
834
835 }
836
837
838 /**
839 * Gracefully terminate the active use of the public methods of this
840 * component. This method should be the last one called on a given
841 * instance of this component.
842 *
843 * @exception LifecycleException if this component detects a fatal error
844 * that needs to be reported
845 */
846 public void stop() throws LifecycleException {
847
848 if( log.isDebugEnabled() )
849 log.debug("Stopping embedded server");
850
851 // Validate and update our current component state
852 if (!started)
853 throw new LifecycleException
854 (sm.getString("embedded.notStarted"));
855 lifecycle.fireLifecycleEvent(STOP_EVENT, null);
856 started = false;
857
858 // Stop our defined Connectors first
859 for (int i = 0; i < connectors.length; i++) {
860 if (connectors[i] instanceof Lifecycle)
861 ((Lifecycle) connectors[i]).stop();
862 }
863
864 // Stop our defined Engines second
865 for (int i = 0; i < engines.length; i++) {
866 if (engines[i] instanceof Lifecycle)
867 ((Lifecycle) engines[i]).stop();
868 }
869
870 }
871
872
873 // ------------------------------------------------------ Protected Methods
874
875
876 /** Initialize naming - this should only enable java:env and root naming.
877 * If tomcat is embeded in an application that already defines those -
878 * it shouldn't do it.
879 *
880 * XXX The 2 should be separated, you may want to enable java: but not
881 * the initial context and the reverse
882 * XXX Can we "guess" - i.e. lookup java: and if something is returned assume
883 * false ?
884 * XXX We have a major problem with the current setting for java: url
885 */
886 protected void initNaming() {
887 // Setting additional variables
888 if (!useNaming) {
889 log.info( "Catalina naming disabled");
890 System.setProperty("catalina.useNaming", "false");
891 } else {
892 System.setProperty("catalina.useNaming", "true");
893 String value = "org.apache.naming";
894 String oldValue =
895 System.getProperty(javax.naming.Context.URL_PKG_PREFIXES);
896 if (oldValue != null) {
897 value = value + ":" + oldValue;
898 }
899 System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value);
900 if( log.isDebugEnabled() )
901 log.debug("Setting naming prefix=" + value);
902 value = System.getProperty
903 (javax.naming.Context.INITIAL_CONTEXT_FACTORY);
904 if (value == null) {
905 System.setProperty
906 (javax.naming.Context.INITIAL_CONTEXT_FACTORY,
907 "org.apache.naming.java.javaURLContextFactory");
908 } else {
909 log.debug( "INITIAL_CONTEXT_FACTORY alread set " + value );
910 }
911 }
912 }
913
914
915 protected void initDirs() {
916
917 String catalinaHome = System.getProperty("catalina.home");
918 if (catalinaHome == null) {
919 // Backwards compatibility patch for J2EE RI 1.3
920 String j2eeHome = System.getProperty("com.sun.enterprise.home");
921 if (j2eeHome != null) {
922 catalinaHome=System.getProperty("com.sun.enterprise.home");
923 } else if (System.getProperty("catalina.base") != null) {
924 catalinaHome = System.getProperty("catalina.base");
925 } else {
926 // Use IntrospectionUtils and guess the dir
927 catalinaHome = IntrospectionUtils.guessInstall
928 ("catalina.home", "catalina.base", "catalina.jar");
929 if (catalinaHome == null) {
930 catalinaHome = IntrospectionUtils.guessInstall
931 ("tomcat.install", "catalina.home", "tomcat.jar");
932 }
933 }
934 }
935 // last resort - for minimal/embedded cases.
936 if(catalinaHome==null) {
937 catalinaHome=System.getProperty("user.dir");
938 }
939 if (catalinaHome != null) {
940 File home = new File(catalinaHome);
941 if (!home.isAbsolute()) {
942 try {
943 catalinaHome = home.getCanonicalPath();
944 } catch (IOException e) {
945 catalinaHome = home.getAbsolutePath();
946 }
947 }
948 System.setProperty("catalina.home", catalinaHome);
949 }
950
951 if (System.getProperty("catalina.base") == null) {
952 System.setProperty("catalina.base",
953 catalinaHome);
954 } else {
955 String catalinaBase = System.getProperty("catalina.base");
956 File base = new File(catalinaBase);
957 if (!base.isAbsolute()) {
958 try {
959 catalinaBase = base.getCanonicalPath();
960 } catch (IOException e) {
961 catalinaBase = base.getAbsolutePath();
962 }
963 }
964 System.setProperty("catalina.base", catalinaBase);
965 }
966
967 String temp = System.getProperty("java.io.tmpdir");
968 if (temp == null || (!(new File(temp)).exists())
969 || (!(new File(temp)).isDirectory())) {
970 log.error(sm.getString("embedded.notmp", temp));
971 }
972
973 }
974
975
976 protected void initStreams() {
977 if (redirectStreams) {
978 // Replace System.out and System.err with a custom PrintStream
979 SystemLogHandler systemlog = new SystemLogHandler(System.out);
980 System.setOut(systemlog);
981 System.setErr(systemlog);
982 }
983 }
984
985
986 // -------------------------------------------------------- Private Methods
987
988 /**
989 * Set the security package access/protection.
990 */
991 protected void setSecurityProtection(){
992 SecurityConfig securityConfig = SecurityConfig.newInstance();
993 securityConfig.setPackageDefinition();
994 securityConfig.setPackageAccess();
995 }
996
997 }