KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > invocation > pooled > server > PooledInvoker


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.pooled.server;
23
24 import java.net.InetAddress JavaDoc;
25 import java.net.ServerSocket JavaDoc;
26 import java.net.Socket JavaDoc;
27 import java.net.UnknownHostException JavaDoc;
28 import java.util.LinkedList JavaDoc;
29 import java.security.PrivilegedExceptionAction JavaDoc;
30 import java.security.AccessController JavaDoc;
31 import java.security.PrivilegedActionException JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33 import java.rmi.NoSuchObjectException JavaDoc;
34 import javax.management.ObjectName JavaDoc;
35 import javax.naming.InitialContext JavaDoc;
36 import javax.transaction.Transaction JavaDoc;
37 import javax.transaction.TransactionManager JavaDoc;
38 import javax.net.SocketFactory;
39 import javax.net.ServerSocketFactory;
40
41 import org.jboss.invocation.Invocation;
42 import org.jboss.invocation.pooled.interfaces.PooledInvokerProxy;
43 import org.jboss.invocation.pooled.interfaces.ServerAddress;
44 import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation;
45 import org.jboss.logging.Logger;
46 import org.jboss.proxy.TransactionInterceptor;
47 import org.jboss.system.Registry;
48 import org.jboss.system.ServiceMBeanSupport;
49 import org.jboss.system.server.ServerConfigUtil;
50 import org.jboss.tm.TransactionPropagationContextFactory;
51 import org.jboss.tm.TransactionPropagationContextImporter;
52 import org.jboss.tm.TransactionPropagationContextUtil;
53 import org.jboss.security.SecurityDomain;
54 import org.jboss.net.sockets.DefaultSocketFactory;
55
56 /**
57  * This invoker pools Threads and client connections to one server socket.
58  * The purpose is to avoid a bunch of failings of RMI.
59  *
60  * 1. Avoid making a client socket connection with every invocation call.
61  * This is very expensive. Also on windows if too many clients try
62  * to connect at the same time, you get connection refused exceptions.
63  * This invoker/proxy combo alleviates this.
64  *
65  * 2. Avoid creating a thread per invocation. The client/server connection
66  * is preserved and attached to the same thread.
67
68  * So we have connection pooling on the server and client side, and thread pooling
69  * on the server side. Pool, is an LRU pool, so resources should be cleaned up.
70  *
71  *
72  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
73  * @author Scott.Stark@jboss.org
74  * @version $Revision: 45652 $
75  *
76  * @jmx:mbean extends="org.jboss.system.ServiceMBean"
77  */

78 public class PooledInvoker extends ServiceMBeanSupport
79    implements PooledInvokerMBean, Runnable JavaDoc
80 {
81
82    /**
83     * logger instance.
84     */

85    final static protected Logger log = Logger.getLogger(PooledInvoker.class);
86
87    /**
88     * If the TcpNoDelay option should be used on the socket.
89     */

90    protected boolean enableTcpNoDelay = false;
91
92    /**
93     * The internet address to bind to by default.
94     */

95    protected String JavaDoc serverBindAddress = null;
96
97    /**
98     * The server port to bind to.
99     */

100    protected int serverBindPort = 0;
101
102    /**
103     * The internet address client will use to connect to the sever.
104     */

105    protected String JavaDoc clientConnectAddress = null;
106
107    /**
108     * The port a client will use to connect to the sever.
109     */

110    protected int clientConnectPort = 0;
111    /**
112     * The number of retry attempts on
113     */

114    protected int clientRetryCount = 1;
115
116    protected int backlog = 200;
117
118    /** The class name of the optional custom client socket factory */
119    protected String JavaDoc clientSocketFactoryName;
120
121    /** The class name of the optional custom server socket factory */
122    protected String JavaDoc serverSocketFactoryName;
123
124    /** An optional custom client socket factory */
125    protected SocketFactory clientSocketFactory;
126
127    /** An optional custom server socket factory */
128    protected ServerSocketFactory serverSocketFactory;
129    /** The server socket for */
130    protected ServerSocket JavaDoc serverSocket = null;
131
132    /** The name of the security domain to use with server sockets that support SSL */
133    protected String JavaDoc sslDomain;
134
135    protected int timeout = 60000; // 60 seconds.
136

137    protected int maxPoolSize = 300;
138
139    protected int clientMaxPoolSize = 300;
140
141    protected int numAcceptThreads = 1;
142    protected Thread JavaDoc[] acceptThreads;
143
144    protected LRUPool clientpool;
145    protected LinkedList JavaDoc threadpool;
146    protected boolean running = true;
147    /** The logging trace level flag */
148    protected boolean trace = false;
149    /**
150     * ObjectName of the <code>transactionManagerService</code> we use.
151     * Probably should not be here -- used to set txInterceptor tx mananger.
152     */

153    protected ObjectName JavaDoc transactionManagerService;
154
155    protected PooledInvokerProxy optimizedInvokerProxy = null;
156    /** A priviledged actions for MBeanServer.invoke when running with sec mgr */
157    private MBeanServerAction serverAction = new MBeanServerAction();
158
159    protected static TransactionPropagationContextFactory tpcFactory;
160    protected static TransactionPropagationContextImporter tpcImporter;
161
162    ////////////////////////////////////////////////////////////////////////
163
//
164
// The following methods Override the ServiceMBeanSupport base class
165
//
166
////////////////////////////////////////////////////////////////////////
167

168    protected void jmxBind()
169    {
170       Registry.bind(getServiceName(), optimizedInvokerProxy);
171    }
172
173    /**
174     * Starts this IL, and binds it to JNDI
175     *
176     * @exception Exception Description of Exception
177     */

178    public void startService() throws Exception JavaDoc
179    {
180       trace = log.isTraceEnabled();
181
182       ///////////////////////////////////////////////////////////
183
// Setup the transaction stuff
184
///////////////////////////////////////////////////////////
185
InitialContext JavaDoc ctx = new InitialContext JavaDoc();
186
187       // Get the transaction propagation context factory
188
tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
189
190       // and the transaction propagation context importer
191
tpcImporter = TransactionPropagationContextUtil.getTPCImporter();
192
193       // FIXME marcf: This should not be here
194
TransactionInterceptor.setTransactionManager((TransactionManager JavaDoc)ctx.lookup("java:/TransactionManager"));
195
196       ///////////////////////////////////////////////////////////
197
// Setup the socket level stuff
198
///////////////////////////////////////////////////////////
199

200       InetAddress JavaDoc bindAddress =
201          (serverBindAddress == null || serverBindAddress.length() == 0)
202             ? null
203             : InetAddress.getByName(serverBindAddress);
204
205       clientConnectAddress =
206          (clientConnectAddress == null || clientConnectAddress.length() == 0)
207             ? InetAddress.getLocalHost().getHostName()
208             : clientConnectAddress;
209       /* We need to check the address against "0.0.0.0" as this is not a valid
210       address although some jdks will default to the host, while others fail
211       with java.net.BindException: Cannot assign requested address: connect
212       */

213       clientConnectAddress = ServerConfigUtil.fixRemoteAddress(clientConnectAddress);
214
215       // Load any custom socket factories
216
loadCustomSocketFactories();
217
218       clientpool = new LRUPool(2, maxPoolSize);
219       clientpool.create();
220       threadpool = new LinkedList JavaDoc();
221        try
222        {
223           if( serverSocketFactory != null )
224             serverSocket = serverSocketFactory.createServerSocket(serverBindPort, backlog, bindAddress);
225           else
226             serverSocket = new ServerSocket JavaDoc(serverBindPort, backlog, bindAddress);
227        }
228        catch( java.net.BindException JavaDoc be)
229        {
230            throw new Exception JavaDoc("Port "+serverBindPort+" is already in use",be);
231        }
232        serverBindPort = serverSocket.getLocalPort();
233       clientConnectPort = (clientConnectPort == 0) ? serverSocket.getLocalPort() : clientConnectPort;
234
235       ServerAddress sa = new ServerAddress(clientConnectAddress, clientConnectPort,
236          enableTcpNoDelay, timeout, clientSocketFactory);
237       optimizedInvokerProxy = new PooledInvokerProxy(sa, clientMaxPoolSize, clientRetryCount);
238
239       ///////////////////////////////////////////////////////////
240
// Register the service with the rest of the JBoss Kernel
241
///////////////////////////////////////////////////////////
242
// Export references to the bean
243
jmxBind();
244       log.debug("Bound invoker for JMX node");
245       ctx.close();
246
247       acceptThreads = new Thread JavaDoc[numAcceptThreads];
248       for (int i = 0; i < numAcceptThreads; i++)
249       {
250          String JavaDoc name = "PooledInvokerAcceptor#"+i+"-"+serverBindPort;
251          acceptThreads[i] = new Thread JavaDoc(this, name);
252          acceptThreads[i].start();
253       }
254    }
255
256    public void run()
257    {
258       while (running)
259       {
260          try
261          {
262             Socket JavaDoc socket = serverSocket.accept();
263             if( trace )
264                log.trace("Accepted: "+socket);
265             ServerThread thread = null;
266             boolean newThread = false;
267             
268             while (thread == null)
269             {
270                synchronized(threadpool)
271                {
272                   if (threadpool.size() > 0)
273                   {
274                      thread = (ServerThread)threadpool.removeFirst();
275                   }
276                }
277                if (thread == null)
278                {
279                   synchronized(clientpool)
280                   {
281                      if (clientpool.size() < maxPoolSize)
282                      {
283                         thread = new ServerThread(socket, this, clientpool, threadpool, timeout);
284                         newThread = true;
285                      }
286                      if (thread == null)
287                      {
288                         clientpool.evict();
289                         if( trace )
290                            log.trace("Waiting for a thread...");
291                         clientpool.wait();
292                         if( trace )
293                            log.trace("Notified of available thread");
294                      }
295                   }
296                }
297             }
298             synchronized(clientpool)
299             {
300                clientpool.insert(thread, thread);
301             }
302             
303             if (newThread)
304             {
305                if( trace )
306                   log.trace("Created a new thread, t="+thread);
307                thread.start();
308             }
309             else
310             {
311                if( trace )
312                   log.trace("Reusing thread t="+thread);
313                thread.wakeup(socket, timeout);
314             }
315          }
316          catch (Throwable JavaDoc ex)
317          {
318             if (running)
319                log.error("Failed to accept socket connection", ex);
320          }
321       }
322    }
323
324    /**
325     * Stops this service, and unbinds it from JNDI.
326     */

327    public void stopService() throws Exception JavaDoc
328    {
329       running = false;
330       maxPoolSize = 0; // so ServerThreads don't reinsert themselves
331
for (int i = 0; i < acceptThreads.length; i++)
332       {
333          try
334          {
335             acceptThreads[i].interrupt();
336          }
337          catch (Exception JavaDoc ignored){}
338       }
339       clientpool.flush();
340       for (int i = 0; i < threadpool.size(); i++)
341       {
342          ServerThread thread = (ServerThread)threadpool.removeFirst();
343          thread.shutdown();
344       }
345
346       try
347       {
348          serverSocket.close();
349       }
350       catch(Exception JavaDoc e)
351       {
352       }
353    }
354
355    protected void destroyService() throws Exception JavaDoc
356    {
357       // Unexport references to the bean
358
Registry.unbind(getServiceName());
359    }
360
361    /**
362     * The ServerProtocol will use this method to service an invocation
363     * request.
364     */

365    public Object JavaDoc invoke(Invocation invocation) throws Exception JavaDoc
366    {
367       Thread JavaDoc currentThread = Thread.currentThread();
368       ClassLoader JavaDoc oldCl = currentThread.getContextClassLoader();
369       try
370       {
371
372          // Deserialize the transaction if it is there
373
PooledMarshalledInvocation mi = (PooledMarshalledInvocation) invocation;
374          invocation.setTransaction(importTPC(mi.getTransactionPropagationContext()));
375          ObjectName JavaDoc mbean = (ObjectName JavaDoc) Registry.lookup(invocation.getObjectName());
376          if( mbean == null )
377          {
378             System.err.println("NoSuchObjectException: "+invocation.getObjectName());
379             throw new NoSuchObjectException JavaDoc("Failed to find target for objectName: "+invocation.getObjectName());
380          }
381
382          // The cl on the thread should be set in another interceptor
383
Object JavaDoc obj = serverAction.invoke(mbean, "invoke",
384                new Object JavaDoc[] { invocation }, Invocation.INVOKE_SIGNATURE);
385
386          return obj;
387       }
388       catch (Exception JavaDoc e)
389       {
390          org.jboss.mx.util.JMXExceptionDecoder.rethrow(e);
391
392          // the compiler does not know an exception is thrown by the above
393
throw new org.jboss.util.UnreachableStatementException();
394       }
395       finally
396       {
397          currentThread.setContextClassLoader(oldCl);
398       }
399    }
400
401    protected Transaction JavaDoc importTPC(Object JavaDoc tpc)
402    {
403       if (tpc != null)
404          return tpcImporter.importTransactionPropagationContext(tpc);
405       return null;
406    }
407
408    //The following are the mbean attributes for TrunkInvoker
409

410    /**
411     * Getter for property numAcceptThreads
412     *
413     * @return Value of property numAcceptThreads
414     * @jmx:managed-attribute
415     */

416    public int getNumAcceptThreads()
417    {
418       return numAcceptThreads;
419    }
420
421    /**
422     * Setter for property numAcceptThreads
423     *
424     * @param size New value of property numAcceptThreads.
425     * @jmx:managed-attribute
426     */

427    public void setNumAcceptThreads(int size)
428    {
429       this.numAcceptThreads = size;
430    }
431
432    /**
433     * Getter for property maxPoolSize;
434     *
435     * @return Value of property maxPoolSize.
436     * @jmx:managed-attribute
437     */

438    public int getMaxPoolSize()
439    {
440       return maxPoolSize;
441    }
442
443    /**
444     * Setter for property maxPoolSize.
445     *
446     * @param maxPoolSize New value of property maxPoolSize.
447     * @jmx:managed-attribute
448     */

449    public void setMaxPoolSize(int maxPoolSize)
450    {
451       this.maxPoolSize = maxPoolSize;
452    }
453
454    /**
455     * Getter for property maxPoolSize;
456     *
457     * @return Value of property maxPoolSize.
458     * @jmx:managed-attribute
459     */

460    public int getClientMaxPoolSize()
461    {
462       return clientMaxPoolSize;
463    }
464
465    /**
466     * Setter for property maxPoolSize.
467     *
468     * @param clientMaxPoolSize New value of property serverBindPort.
469     * @jmx:managed-attribute
470     */

471    public void setClientMaxPoolSize(int clientMaxPoolSize)
472    {
473       this.clientMaxPoolSize = clientMaxPoolSize;
474    }
475
476    /**
477     * Getter for property timeout
478     *
479     * @return Value of property timeout
480     * @jmx:managed-attribute
481     */

482    public int getSocketTimeout()
483    {
484       return timeout;
485    }
486
487    /**
488     * Setter for property timeout
489     *
490     * @param time New value of property timeout
491     * @jmx:managed-attribute
492     */

493    public void setSocketTimeout(int time)
494    {
495       this.timeout = time;
496    }
497
498    /**
499     *
500     * @return Value of property CurrentClientPoolSize.
501     * @jmx:managed-attribute
502     */

503    public int getCurrentClientPoolSize()
504    {
505       return clientpool.size();
506    }
507
508    /**
509     *
510     * @return Value of property CurrentThreadPoolSize.
511     * @jmx:managed-attribute
512     */

513    public int getCurrentThreadPoolSize()
514    {
515       return threadpool.size();
516    }
517
518    /**
519     * Getter for property serverBindPort.
520     *
521     * @return Value of property serverBindPort.
522     * @jmx:managed-attribute
523     */

524    public int getServerBindPort()
525    {
526       return serverBindPort;
527    }
528
529    /**
530     * Setter for property serverBindPort.
531     *
532     * @param serverBindPort New value of property serverBindPort.
533     * @jmx:managed-attribute
534     */

535    public void setServerBindPort(int serverBindPort)
536    {
537       this.serverBindPort = serverBindPort;
538    }
539
540    /**
541     * @jmx:managed-attribute
542     */

543    public String JavaDoc getClientConnectAddress()
544    {
545       return clientConnectAddress;
546    }
547
548    /**
549     * @jmx:managed-attribute
550     */

551    public void setClientConnectAddress(String JavaDoc clientConnectAddress)
552    {
553       this.clientConnectAddress = clientConnectAddress;
554    }
555
556    /**
557     * @jmx:managed-attribute
558     */

559    public int getClientConnectPort()
560    {
561       return clientConnectPort;
562    }
563
564    /**
565     * @jmx:managed-attribute
566     */

567    public void setClientConnectPort(int clientConnectPort)
568    {
569       this.clientConnectPort = clientConnectPort;
570    }
571
572    /**
573     * @jmx:managed-attribute
574     */

575    public int getClientRetryCount()
576    {
577       return clientRetryCount;
578    }
579
580    /**
581     * @jmx:managed-attribute
582     */

583    public void setClientRetryCount(int clientRetryCount)
584    {
585       this.clientRetryCount = clientRetryCount;
586    }
587
588    /**
589     * @jmx:managed-attribute
590     */

591    public int getBacklog()
592    {
593       return backlog;
594    }
595
596    /**
597     * @jmx:managed-attribute
598     */

599    public void setBacklog(int backlog)
600    {
601       this.backlog = backlog;
602    }
603
604    /**
605     * @jmx:managed-attribute
606     */

607    public boolean isEnableTcpNoDelay()
608    {
609       return enableTcpNoDelay;
610    }
611
612    /**
613     * @jmx:managed-attribute
614     */

615    public void setEnableTcpNoDelay(boolean enableTcpNoDelay)
616    {
617       this.enableTcpNoDelay = enableTcpNoDelay;
618    }
619
620    /**
621     * @jmx:managed-attribute
622     */

623    public String JavaDoc getServerBindAddress()
624    {
625       return serverBindAddress;
626    }
627
628    /**
629     * @jmx:managed-attribute
630     */

631    public void setServerBindAddress(String JavaDoc serverBindAddress)
632    {
633       this.serverBindAddress = serverBindAddress;
634    }
635
636    /**
637     * @jmx:managed-attribute
638     */

639    public String JavaDoc getClientSocketFactoryName()
640    {
641       return clientSocketFactoryName;
642    }
643
644    /**
645     * @jmx:managed-attribute
646     */

647    public void setClientSocketFactoryName(String JavaDoc clientSocketFactoryName)
648    {
649       this.clientSocketFactoryName = clientSocketFactoryName;
650    }
651
652    /**
653     * @jmx:managed-attribute
654     */

655    public String JavaDoc getServerSocketFactoryName()
656    {
657       return serverSocketFactoryName;
658    }
659
660    /**
661     * @jmx:managed-attribute
662     */

663    public void setServerSocketFactoryName(String JavaDoc serverSocketFactoryName)
664    {
665       this.serverSocketFactoryName = serverSocketFactoryName;
666    }
667
668    /**
669     * @jmx:managed-attribute
670     */

671    public SocketFactory getClientSocketFactory()
672    {
673       return clientSocketFactory;
674    }
675
676    /**
677     * @jmx:managed-attribute
678     */

679    public void setClientSocketFactory(SocketFactory clientSocketFactory)
680    {
681       this.clientSocketFactory = clientSocketFactory;
682    }
683
684    /**
685     * @jmx:managed-attribute
686     */

687    public ServerSocket JavaDoc getServerSocket()
688    {
689       return serverSocket;
690    }
691
692    /**
693     * @jmx:managed-attribute
694     */

695    public void setServerSocket(ServerSocket JavaDoc serverSocket)
696    {
697       this.serverSocket = serverSocket;
698    }
699
700    /**
701     * @jmx:managed-attribute
702     */

703    public String JavaDoc getSslDomain()
704    {
705       return sslDomain;
706    }
707
708    /**
709     * @jmx:managed-attribute
710     */

711    public void setSslDomain(String JavaDoc sslDomain)
712    {
713       this.sslDomain = sslDomain;
714    }
715
716    /**
717     * @jmx:managed-attribute
718     */

719    public ServerSocketFactory getServerSocketFactory()
720    {
721       return serverSocketFactory;
722    }
723
724    /**
725     * @jmx:managed-attribute
726     */

727    public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)
728    {
729       this.serverSocketFactory = serverSocketFactory;
730    }
731    
732    /**
733     * mbean get-set pair for field transactionManagerService
734     * Get the value of transactionManagerService
735     * @return value of transactionManagerService
736     *
737     * @jmx:managed-attribute
738     */

739    public ObjectName JavaDoc getTransactionManagerService()
740    {
741       return transactionManagerService;
742    }
743    
744    
745    /**
746     * Set the value of transactionManagerService
747     * @param transactionManagerService Value to assign to transactionManagerService
748     *
749     * @jmx:managed-attribute
750     */

751    public void setTransactionManagerService(ObjectName JavaDoc transactionManagerService)
752    {
753       this.transactionManagerService = transactionManagerService;
754    }
755    
756    /**
757     * @jmx:managed-attribute
758     */

759    public PooledInvokerProxy getOptimizedInvokerProxy()
760    {
761       return optimizedInvokerProxy;
762    }
763
764    /** Load and instantiate the clientSocketFactory, serverSocketFactory using
765     the TCL and set the bind address and SSL domain if the serverSocketFactory
766     supports it.
767    */

768    protected void loadCustomSocketFactories()
769    {
770       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
771
772       try
773       {
774          if( clientSocketFactoryName != null )
775          {
776             Class JavaDoc csfClass = loader.loadClass(clientSocketFactoryName);
777             clientSocketFactory = (SocketFactory) csfClass.newInstance();
778          }
779       }
780       catch (Exception JavaDoc e)
781       {
782          log.error("Failed to load client socket factory", e);
783          clientSocketFactory = null;
784       }
785
786       try
787       {
788          if( serverSocketFactory == null )
789          {
790             if( serverSocketFactoryName != null )
791             {
792                Class JavaDoc ssfClass = loader.loadClass(serverSocketFactoryName);
793                serverSocketFactory = (ServerSocketFactory) ssfClass.newInstance();
794                if( serverBindAddress != null )
795                {
796                   // See if the server socket supports setBindAddress(String)
797
try
798                   {
799                      Class JavaDoc[] parameterTypes = {String JavaDoc.class};
800                      Method JavaDoc m = ssfClass.getMethod("setBindAddress", parameterTypes);
801                      Object JavaDoc[] args = {serverBindAddress};
802                      m.invoke(serverSocketFactory, args);
803                   }
804                   catch (NoSuchMethodException JavaDoc e)
805                   {
806                      log.warn("Socket factory does not support setBindAddress(String)");
807                      // Go with default address
808
}
809                   catch (Exception JavaDoc e)
810                   {
811                      log.warn("Failed to setBindAddress="+serverBindAddress+" on socket factory", e);
812                      // Go with default address
813
}
814                }
815                /* See if the server socket supports setSecurityDomain(SecurityDomain)
816                if an sslDomain was specified
817                */

818                if( sslDomain != null )
819                {
820                   try
821                   {
822                      InitialContext JavaDoc ctx = new InitialContext JavaDoc();
823                      SecurityDomain domain = (SecurityDomain) ctx.lookup(sslDomain);
824                      Class JavaDoc[] parameterTypes = {SecurityDomain.class};
825                      Method JavaDoc m = ssfClass.getMethod("setSecurityDomain", parameterTypes);
826                      Object JavaDoc[] args = {domain};
827                      m.invoke(serverSocketFactory, args);
828                   }
829                   catch(NoSuchMethodException JavaDoc e)
830                   {
831                      log.error("Socket factory does not support setSecurityDomain(SecurityDomain)");
832                   }
833                   catch(Exception JavaDoc e)
834                   {
835                      log.error("Failed to setSecurityDomain="+sslDomain+" on socket factory", e);
836                   }
837                }
838             }
839             // If a bind address was specified create a DefaultSocketFactory
840
else if( serverBindAddress != null )
841             {
842                DefaultSocketFactory defaultFactory = new DefaultSocketFactory(backlog);
843                serverSocketFactory = defaultFactory;
844                try
845                {
846                   defaultFactory.setBindAddress(serverBindAddress);
847                }
848                catch (UnknownHostException JavaDoc e)
849                {
850                   log.error("Failed to setBindAddress="+serverBindAddress+" on socket factory", e);
851                }
852             }
853          }
854       }
855       catch (Exception JavaDoc e)
856       {
857          log.error("operation failed", e);
858          serverSocketFactory = null;
859       }
860    }
861
862    /** Perform the MBeanServer.invoke op in a PrivilegedExceptionAction if
863     * running with a security manager.
864     */

865    class MBeanServerAction implements PrivilegedExceptionAction JavaDoc
866    {
867       private ObjectName JavaDoc target;
868       String JavaDoc method;
869       Object JavaDoc[] args;
870       String JavaDoc[] sig;
871
872       MBeanServerAction()
873       {
874       }
875       MBeanServerAction(ObjectName JavaDoc target, String JavaDoc method, Object JavaDoc[] args, String JavaDoc[] sig)
876       {
877          this.target = target;
878          this.method = method;
879          this.args = args;
880          this.sig = sig;
881       }
882
883       public Object JavaDoc run() throws Exception JavaDoc
884       {
885          Object JavaDoc rtnValue = server.invoke(target, method, args, sig);
886          return rtnValue;
887       }
888       Object JavaDoc invoke(ObjectName JavaDoc target, String JavaDoc method, Object JavaDoc[] args, String JavaDoc[] sig)
889          throws Exception JavaDoc
890       {
891          SecurityManager JavaDoc sm = System.getSecurityManager();
892          Object JavaDoc rtnValue = null;
893          if( sm == null )
894          {
895             // Direct invocation on MBeanServer
896
rtnValue = server.invoke(target, method, args, sig);
897          }
898          else
899          {
900             try
901             {
902                // Encapsulate the invocation in a PrivilegedExceptionAction
903
MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
904                rtnValue = AccessController.doPrivileged(action);
905             }
906             catch (PrivilegedActionException JavaDoc e)
907             {
908                Exception JavaDoc ex = e.getException();
909                throw ex;
910             }
911          }
912          return rtnValue;
913       }
914    }
915 }
916 // vim:expandtab:tabstop=3:shiftwidth=3
917
Popular Tags