KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > server > Embedded


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: Embedded.java 1164 2006-10-18 13:43:42Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.server;
27
28 import java.io.File JavaDoc;
29 import java.rmi.RemoteException JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.ListIterator JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import javax.naming.Context JavaDoc;
37 import javax.naming.InitialContext JavaDoc;
38 import javax.naming.NamingException JavaDoc;
39
40 import org.objectweb.easybeans.api.EZBArchive;
41 import org.objectweb.easybeans.api.EZBContainer;
42 import org.objectweb.easybeans.api.EZBContainerConfig;
43 import org.objectweb.easybeans.api.EZBServer;
44 import org.objectweb.easybeans.component.ComponentManager;
45 import org.objectweb.easybeans.component.Components;
46 import org.objectweb.easybeans.component.api.EZBComponent;
47 import org.objectweb.easybeans.component.api.EZBComponentException;
48 import org.objectweb.easybeans.component.itf.RegistryComponent;
49 import org.objectweb.easybeans.container.JContainer3;
50 import org.objectweb.easybeans.container.JContainerConfig;
51 import org.objectweb.easybeans.deployer.Deployer;
52 import org.objectweb.easybeans.jmx.CommonsModelerException;
53 import org.objectweb.easybeans.jmx.CommonsModelerHelper;
54 import org.objectweb.easybeans.jmx.JMXRemoteException;
55 import org.objectweb.easybeans.jmx.JMXRemoteHelper;
56 import org.objectweb.easybeans.jmx.MBeanServerException;
57 import org.objectweb.easybeans.jmx.MBeanServerHelper;
58 import org.objectweb.easybeans.jmx.MBeansException;
59 import org.objectweb.easybeans.jmx.MBeansHelper;
60 import org.objectweb.easybeans.log.JLog;
61 import org.objectweb.easybeans.log.JLogFactory;
62 import org.objectweb.easybeans.rpc.rmi.server.RMIServerRPC;
63 import org.objectweb.easybeans.rpc.rmi.server.RMIServerRPCImpl;
64 import org.objectweb.easybeans.security.jacc.PolicyProvider;
65
66 /**
67  * Allows to create an embedded EJB3 server.
68  * @author Florent Benoit
69  */

70 public class Embedded implements EZBServer {
71
72     /**
73      * Default sleep value (for server loop).
74      */

75     private static final int SLEEP_VALUE = 10000;
76
77     /**
78      * Logger.
79      */

80     private static JLog logger = JLogFactory.getLog(Embedded.class);
81
82     /**
83      * Internal (global) counter of all embedded instance created.
84      */

85     private static int counter = 0;
86
87     /**
88      * ID of this embedded server.
89      */

90     private Integer JavaDoc id = null;
91
92     /**
93      * Configuration of this server.
94      */

95     private ServerConfig serverConfig = null;
96
97     /**
98      * Map of managed ejb3 containers.
99      */

100     private Map JavaDoc<String JavaDoc, EZBContainer> containers = null;
101
102     /**
103      * List of Callbacks factories.
104      */

105     private List JavaDoc<EasyBeansConfigurationExtension> extensionFactories = null;
106
107     /**
108      * Deployer instance.
109      */

110     private Deployer deployer = null;
111
112     /**
113      * List of components that have been defined.
114      */

115     private Components components = null;
116
117     /**
118      * Manager of components.
119      */

120     private ComponentManager componentManager = null;
121
122     /**
123      * Server started ?
124      */

125     private boolean started = false;
126
127     /**
128      * Monitor of the containers.
129      */

130     private ContainersMonitor monitor = null;
131
132     /**
133      * Creates a new Embedded server.<br>
134      * It will take default values of configuration.
135      */

136     public Embedded() {
137         this.id = new Integer JavaDoc(counter++);
138         this.containers = new HashMap JavaDoc<String JavaDoc, EZBContainer>();
139         this.extensionFactories = new ArrayList JavaDoc<EasyBeansConfigurationExtension>();
140         this.serverConfig = new ServerConfig();
141         // register to the list
142
EmbeddedManager.addEmbedded(this);
143     }
144
145     /**
146      * Starts the EJB3 server.
147      * @throws EmbeddedException if there is a failure while starting the
148      * server.
149      */

150     public void start() throws EmbeddedException {
151         long tStart = System.currentTimeMillis();
152
153         // Init JACC
154
if (serverConfig.initJACC()) {
155             PolicyProvider.init();
156         }
157
158
159         // configure
160
configure();
161
162         // Define component manager
163
componentManager = new ComponentManager(components);
164
165         // Init components
166
try {
167             componentManager.initComponents();
168         } catch (EZBComponentException e) {
169             throw new EmbeddedException("Cannot init components", e);
170         }
171
172         // Start components
173
try {
174             componentManager.startComponents();
175         } catch (EZBComponentException e) {
176             throw new EmbeddedException("Cannot start components", e);
177         }
178
179         // Use ExtensionFactories ?
180
if (!serverConfig.getExtensionFactories().isEmpty()) {
181             List JavaDoc<String JavaDoc> classnames = serverConfig.getExtensionFactories();
182             for (String JavaDoc fqn : classnames) {
183                 EasyBeansConfigurationExtension factory = null;
184                 try {
185                     factory = Class.forName(fqn).asSubclass(EasyBeansConfigurationExtension.class).newInstance();
186                 } catch (Exception JavaDoc e) {
187                     throw new EmbeddedException("Cannot instantiate CallbackFacory : " + fqn, e);
188                 }
189                 this.extensionFactories.add(factory);
190             }
191         }
192
193         if (serverConfig.isUsingNaming()) {
194             // url.pkg for java:
195
System.setProperty(Context.URL_PKG_PREFIXES, "org.objectweb.easybeans.naming.pkg");
196         }
197
198         // set the deployer used for this component.
199
deployer = new Deployer(this);
200
201         MBeansHelper.getInstance().activate(serverConfig.isUsingMBeans());
202         if (serverConfig.isUsingMBeans()) {
203
204             // init Modeler Registry
205
try {
206                 CommonsModelerHelper.initRegistry();
207             } catch (CommonsModelerException e) {
208                 throw new EmbeddedException("Cannot init MBean server", e);
209             }
210
211             // Start MBeanServer (if any)
212
try {
213                 MBeanServerHelper.startMBeanServer();
214             } catch (MBeanServerException e) {
215                 throw new EmbeddedException("Cannot start MBean server", e);
216             }
217
218             try {
219                 JMXRemoteHelper.startConnector((RegistryComponent) this
220                         .getComponent("org.objectweb.easybeans.component.carol.CarolComponent"));
221             } catch (JMXRemoteException e) {
222                 throw new EmbeddedException("Cannot start JMX Remote connector", e);
223             }
224
225             // register the Deployer
226
try {
227                 MBeansHelper.getInstance().registerMBean(deployer);
228             } catch (MBeansException e) {
229                 throw new EmbeddedException("Cannot init MBeans", e);
230             }
231
232             // register the Server
233
try {
234                 MBeansHelper.getInstance().registerMBean(this);
235             } catch (MBeansException e) {
236                 throw new EmbeddedException("Cannot init MBeans", e);
237             }
238         }
239
240         // Bind the RPC object
241
RMIServerRPC invoker = null;
242         try {
243             invoker = new RMIServerRPCImpl(this);
244         } catch (RemoteException JavaDoc e) {
245             throw new EmbeddedException("Cannot build RPC invoker", e);
246         }
247         try {
248             new InitialContext JavaDoc().rebind(RMIServerRPC.RPC_JNDI_NAME, invoker);
249         } catch (NamingException JavaDoc e) {
250             throw new EmbeddedException("Cannot bind the RPC invoker", e);
251         }
252
253
254         if (serverConfig.isDirectoryScanningEnabled()) {
255             // add a thread which monitor containers file
256
monitor = new ContainersMonitor(this);
257             monitor.init();
258         }
259
260         logger.info("Embedded.start.startup", Version.VERSION, Long.valueOf(System.currentTimeMillis() - tStart));
261         logger.info("Embedded.start.created", Integer.valueOf(containers.size()));
262
263         logger.info("Embedded.start.waiting");
264         if (serverConfig.isDirectoryScanningEnabled()) {
265             monitor.start();
266         }
267
268         // It is started
269
started = true;
270
271         if (serverConfig.shouldWait()) {
272             while (true) {
273                 try {
274                     Thread.sleep(SLEEP_VALUE);
275                 } catch (InterruptedException JavaDoc e) {
276                     e.printStackTrace();
277                 }
278             }
279         }
280     }
281
282     /**
283      * Stops the EJB3 server.
284      * @throws EmbeddedException if container cannot be stopped.
285      */

286     public synchronized void stop() throws EmbeddedException {
287         // ensure started
288
if (!started) {
289             throw new EmbeddedException("Cannot stop the server as it is not started.");
290         }
291
292         // Stop the containers
293
// Use a ListIterator to allow us to safely remove EZBContainers
294
// from the List being processed.
295
List JavaDoc<EZBContainer> containersList = new ArrayList JavaDoc<EZBContainer>(this.containers.values());
296         ListIterator JavaDoc<EZBContainer> li = containersList.listIterator();
297         while (li.hasNext()) {
298             EZBContainer container = li.next();
299             container.stop();
300             removeContainer(container);
301         }
302         monitor.stopOrder();
303
304         // Unregister MBeans
305
if (serverConfig.isUsingMBeans()) {
306
307             // Stop the JMX Connector
308
try {
309                 JMXRemoteHelper.stopConnector();
310             } catch (JMXRemoteException e) {
311                 // Only log the Exception
312
logger.error("Cannot stop JMX Remote connector", e);
313                 // and continue ...
314
}
315
316             // Unregister the Deployer
317
try {
318                 MBeansHelper.getInstance().unregisterMBean(deployer);
319             } catch (MBeansException e) {
320                 // Only log the Exception
321
logger.error("Cannot unregister Deployer MBean", e);
322             }
323
324             // Unregister the Server
325
try {
326                 MBeansHelper.getInstance().unregisterMBean(this);
327             } catch (MBeansException e) {
328                 // Only log the Exception
329
logger.error("Cannot unregister Embedded MBean", e);
330             }
331         }
332
333         // Unbind the RPCInvoker Remote Object
334
try {
335             new InitialContext JavaDoc().unbind(RMIServerRPC.RPC_JNDI_NAME);
336         } catch (NamingException JavaDoc e) {
337             // Only log the Exception
338
logger.error("Cannot unbind the RPC invoker", e);
339         }
340
341         // Stop the components
342
componentManager.stopComponents();
343
344         logger.info("Embedded.stop.stopped", Version.VERSION);
345     }
346
347     /**
348      * Sets the server configuration (not the components).
349      * @param serverConfig the given configuration
350      */

351     public void setServerConfig(final ServerConfig serverConfig) {
352         // check status
353
if (started) {
354             throw new IllegalStateException JavaDoc("Cannot set the server configuration when server has been started.");
355         }
356         this.serverConfig = serverConfig;
357     }
358
359     /**
360      * Gets a container managed by this server.
361      * @param id the container id.
362      * @return the container if it is found, else null.
363      */

364     public EZBContainer getContainer(final String JavaDoc id) {
365         return containers.get(id);
366     }
367
368     /**
369      * Configure the server by using the given configuration.
370      */

371     private void configure() {
372         File JavaDoc ejb3Directory = serverConfig.getEjb3Directory();
373         // need to define a repository
374
if (ejb3Directory == null) {
375             ejb3Directory = new File JavaDoc("ejb3s");
376             logger.debug("No directory was configured, take the default value of '" + ejb3Directory.getAbsolutePath() + "'.");
377             if (!ejb3Directory.exists()) {
378                 if (ejb3Directory.mkdir()) {
379                     logger.warn("Directory '" + ejb3Directory.getAbsolutePath() + "' created.");
380                 } else {
381                     throw new IllegalStateException JavaDoc("Cannot make directory '" + ejb3Directory.getAbsolutePath() + "'.");
382                 }
383             }
384             // update the value
385
serverConfig.setEjb3Path(ejb3Directory.getAbsolutePath());
386         }
387     }
388
389     /**
390      * Creates and adds an ejb3 container to the managed container.
391      * @param archive jar file or exploded archive.
392      * @return the created container.
393      */

394     public EZBContainer createContainer(final EZBArchive archive) {
395         EZBContainerConfig jConfig = new JContainerConfig(archive);
396         jConfig.setEZBServer(this);
397         callJContainerConfigExtensions(jConfig);
398         EZBContainer container = new JContainer3(jConfig);
399
400         addContainer(container);
401
402         return container;
403     }
404
405     /**
406      * Add an already created container.
407      * @param container the EZBContainer to be added.
408      */

409     public void addContainer(final EZBContainer container) {
410         String JavaDoc id = container.getId();
411         containers.put(id, container);
412
413         try {
414             MBeansHelper.getInstance().registerMBean(container);
415         } catch (MBeansException e) {
416             // TODO what to do here ? log or exception ?
417
logger.error("Cannot register Container MBeans for " + container.getArchive().getName(), e);
418         }
419     }
420
421     /**
422      * Remove a given container.
423      * @param container the container to be removed.
424      */

425     public void removeContainer(final EZBContainer container) {
426         containers.remove(container.getId());
427
428         try {
429             MBeansHelper.getInstance().unregisterMBean(container);
430         } catch (MBeansException e) {
431             // TODO what to do here ? log or exception ?
432
logger.error("Cannot unregister Container MBeans for " + container.getArchive().getName(), e);
433         }
434     }
435
436     /**
437      * Adapt the JContainerConfig for all
438      * {@link EasyBeansConfigurationExtension}.
439      * @param jcc the JContainerConfig to adapt.
440      */

441     private void callJContainerConfigExtensions(final EZBContainerConfig jcc) {
442
443         for (EasyBeansConfigurationExtension extension : this.extensionFactories) {
444             try {
445                 extension.configure(jcc);
446             } catch (Throwable JavaDoc t) {
447                 // prevent malicious code to break everything ...
448
logger.info("Failed to configure JContainerConfig with {0}", extension.getClass().getName());
449             }
450         }
451     }
452
453     /**
454      * @return the configuration of this server.
455      */

456     public ServerConfig getServerConfig() {
457         return serverConfig;
458     }
459
460     /**
461      * @return the containers managed by this server.
462      */

463     public Map JavaDoc<String JavaDoc, EZBContainer> getContainers() {
464         return containers;
465     }
466
467     /**
468      * Gets the id of this embedded server.
469      * @return the id of this server.
470      */

471     public Integer JavaDoc getID() {
472         return id;
473     }
474
475     /**
476      * @return Returns the linked Deployer instance.
477      */

478     public Deployer getDeployer() {
479         return deployer;
480     }
481
482     /**
483      * Gets the components that have been defined for this embedded server.
484      * @return the components.
485      */

486     public Components getComponents() {
487         return this.components;
488     }
489
490     /**
491      * Sets the components that needs to be launched.
492      * @param components the set of components.
493      */

494     public void setComponents(final Components components) {
495         this.components = components;
496     }
497
498     /**
499      * Gets component with the given name.
500      * @param componentName the name of the component.
501      * @return the component (if any)
502      */

503     public EZBComponent getComponent(final String JavaDoc componentName) {
504         // ask registry if present.
505
if (componentManager != null) {
506             return componentManager.getComponentRegistry().getComponent(componentName);
507         }
508         return null;
509     }
510
511     /**
512      * @return Returns the ComponentManager used by this instance.
513      */

514     public ComponentManager getComponentManager() {
515         return componentManager;
516     }
517 }
518
Popular Tags