KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > invocation > unified > server > UnifiedInvoker


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.invocation.unified.server;
23
24 import java.rmi.MarshalledObject JavaDoc;
25 import javax.management.MBeanServer JavaDoc;
26 import javax.management.ObjectName JavaDoc;
27 import org.jboss.invocation.Invocation;
28 import org.jboss.invocation.unified.interfaces.UnifiedInvokerProxy;
29 import org.jboss.mx.util.JMXExceptionDecoder;
30 import org.jboss.remoting.InvocationRequest;
31 import org.jboss.remoting.InvokerLocator;
32 import org.jboss.remoting.ServerInvocationHandler;
33 import org.jboss.remoting.ServerInvoker;
34 import org.jboss.remoting.callback.InvokerCallbackHandler;
35 import org.jboss.remoting.transport.ConnectorMBean;
36 import org.jboss.system.Registry;
37 import org.jboss.system.ServiceMBeanSupport;
38
39 /**
40  * This is a detached invoker which sits on top of jboss remoting.
41  * Since this uses remoting, the transport protocol used is defined within
42  * the remoting service and this, the UnifiedInvoker, is declared as the handler.
43  *
44  * @author <a HREF="mailto:tom.elrod@jboss.com">Tom Elrod</a>
45  */

46 public class UnifiedInvoker extends ServiceMBeanSupport implements ServerInvocationHandler, UnifiedInvokerMBean
47 {
48    private ConnectorMBean connector;
49    private ServerInvoker serverInvoker;
50
51    private MBeanServer JavaDoc mbServer;
52
53    private boolean strictRMIException = false;
54
55    private UnifiedInvokerProxy proxy;
56
57    private String JavaDoc subsystem = "invoker";
58
59    /**
60     * If set to true, this will cause the UnifiedInvokerProxy (on the client side) to
61     * wrap all RemoteExceptions thrown from the server in a new ServerException. If false,
62     * will unwrap the original exception thrown from withint the RemoteException and throw that.
63     * The default is false.
64     *
65     * @param isStrict
66     */

67    public void setStrictRMIException(boolean isStrict)
68    {
69       this.strictRMIException = isStrict;
70    }
71
72    /**
73     * A return of true means that the UnifiedInvokerProxy (on the client side) will wrap all
74     * RemoteExceptions within a new ServerException. A return of false, will unwrap the original
75     * exception thrown from within the RemoteException and throw that. The default, if not explicitly set,
76     * is false.
77     *
78     * @return
79     */

80    public boolean getStrictRMIException()
81    {
82       return strictRMIException;
83    }
84
85    /**
86     * Gets the remoting subsystem being used.
87     * @return
88     */

89    public String JavaDoc getSubSystem()
90    {
91       return subsystem;
92    }
93
94    public void setSubSystem(String JavaDoc subsystem)
95    {
96       this.subsystem = subsystem;
97    }
98
99    /**
100     * This may be called if set depends in config with optional-attribute-name.
101     *
102     * @param connector
103     */

104    public void setConnector(ConnectorMBean connector)
105    {
106       this.connector = connector;
107    }
108
109    protected void createService() throws Exception JavaDoc
110    {
111       if(connector != null)
112       {
113          try
114          {
115             connector.addInvocationHandler(getSubSystem(), this);
116          }
117          catch(Exception JavaDoc e)
118          {
119             log.error("Error adding unified invoker as handler upon connector being set.", e);
120          }
121       }
122    }
123
124    /**
125     * Will get the invoker locator from the server invoker, start the server invoker, create the proxy,
126     * and bind the proxy.
127     *
128     * @throws Exception
129     */

130    protected void startService() throws Exception JavaDoc
131    {
132       log.debug("Starting unified invoker service.");
133
134       InvokerLocator locator = null;
135       if(serverInvoker != null)
136       {
137          locator = serverInvoker.getLocator();
138          if(!serverInvoker.isStarted())
139          {
140             serverInvoker.start();
141          }
142       }
143       else if(connector != null)
144       {
145          locator = connector.getLocator();
146       }
147       else
148       {
149          /**
150           * This will happen in one of two scenarios. One, the unified invoker was not declared in as
151           * service before the connector AND was not specified as the handler within the connector config.
152           * Two, the unified invoker service config did not use the proxy-type attribute within the depends
153           * tag to have the container set the connector upon creating the unified invoker.
154           */

155          log.error("Error referencing either remoting connector or server invoker to be used. " +
156                    "Please check configuration to make sure proper dependancies are set.");
157          throw new RuntimeException JavaDoc("Error getting locator because server invoker is null.");
158       }
159
160       proxy = new UnifiedInvokerProxy(locator, strictRMIException);
161
162       jmxBind();
163
164    }
165
166    protected void jmxBind()
167    {
168       Registry.bind(getServiceName(), proxy);
169    }
170
171    /**
172     * Stops the server invoker.
173     *
174     * @throws Exception
175     */

176    public void stopService() throws Exception JavaDoc
177    {
178       if(serverInvoker != null)
179       {
180          serverInvoker.stop();
181       }
182    }
183
184    /**
185     * Gives this JMX service a name.
186     *
187     * @return The Name value
188     */

189    public String JavaDoc getName()
190    {
191       return "Unified-Invoker";
192    }
193
194    /**
195     * Gets the invoker locator string for this server
196     *
197     * @return
198     */

199    public String JavaDoc getInvokerLocator()
200    {
201       if(serverInvoker != null)
202       {
203          return serverInvoker.getLocator().getLocatorURI();
204       }
205       else
206       {
207          return null;
208       }
209    }
210
211    /**
212     * Implementation of the server invoker handler interface. Will take the invocation request
213     * and invoke down the interceptor chain.
214     *
215     * @param invocationReq
216     * @return
217     * @throws Throwable
218     */

219    public Object JavaDoc invoke(InvocationRequest invocationReq) throws Throwable JavaDoc
220    {
221       Invocation invocation = (Invocation) invocationReq.getParameter();
222       Thread JavaDoc currentThread = Thread.currentThread();
223       ClassLoader JavaDoc oldCl = currentThread.getContextClassLoader();
224       ObjectName JavaDoc mbean = null;
225       try
226       {
227          mbean = (ObjectName JavaDoc) Registry.lookup(invocation.getObjectName());
228
229          // The cl on the thread should be set in another interceptor
230
Object JavaDoc obj = getServer().invoke(mbean,
231                                          "invoke",
232                                          new Object JavaDoc[]{invocation},
233                                          Invocation.INVOKE_SIGNATURE);
234          return new MarshalledObject JavaDoc(obj);
235       }
236       catch(Exception JavaDoc e)
237       {
238          Throwable JavaDoc th = JMXExceptionDecoder.decode(e);
239          if(log.isTraceEnabled())
240          {
241             log.trace("Failed to invoke on mbean: " + mbean, th);
242          }
243
244          if(th instanceof Exception JavaDoc)
245          {
246             e = (Exception JavaDoc) th;
247          }
248
249          throw e;
250       }
251       finally
252       {
253          currentThread.setContextClassLoader(oldCl);
254          Thread.interrupted(); // clear interruption because this thread may be pooled.
255
}
256
257    }
258
259    /**
260     * set the mbean server that the handler can reference
261     *
262     * @param server
263     */

264    public void setMBeanServer(MBeanServer JavaDoc server)
265    {
266       mbServer = server;
267    }
268
269    public MBeanServer JavaDoc getServer()
270    {
271       return mbServer;
272    }
273
274    /**
275     * set the invoker that owns this handler
276     *
277     * @param invoker
278     */

279    public void setInvoker(ServerInvoker invoker)
280    {
281       /**
282        * This is needed in case we need to make calls on the server invoker (for classloading
283        * in particular). Will just leave alone for now and come back to this when have
284        * a use to call on it.
285        */

286       serverInvoker = invoker;
287    }
288
289    protected ServerInvoker getInvoker()
290    {
291       return serverInvoker;
292    }
293
294    /**
295     * Adds a callback handler that will listen for callbacks from
296     * the server invoker handler.
297     * This is a no op as don't expect the detached invokers to have callbacks
298     *
299     * @param callbackHandler
300     */

301    public void addListener(InvokerCallbackHandler callbackHandler)
302    {
303       //NO OP - do not expect the detached invoker to have callbacks
304
}
305
306    /**
307     * Removes the callback handler that was listening for callbacks
308     * from the server invoker handler.
309     * This is a no op as don't expect the detached invokers to have callbacks
310     *
311     * @param callbackHandler
312     */

313    public void removeListener(InvokerCallbackHandler callbackHandler)
314    {
315       //NO OP - do not expect the detached invoker to have callbacks
316
}
317
318 }
Popular Tags