PageRenderTime 63ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/jboss-5.1.0/server/src/main/org/jboss/invocation/pooled/server/PooledInvoker.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 916 lines | 529 code | 96 blank | 291 comment | 47 complexity | 971e1e291aeb636cfa11d1abcfd1fb29 MD5 | raw file
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2008, Red Hat Middleware LLC, and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a 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. import java.net.InetAddress;
  24. import java.net.ServerSocket;
  25. import java.net.Socket;
  26. import java.net.UnknownHostException;
  27. import java.util.LinkedList;
  28. import java.security.PrivilegedExceptionAction;
  29. import java.security.AccessController;
  30. import java.security.PrivilegedActionException;
  31. import java.lang.reflect.Method;
  32. import java.rmi.NoSuchObjectException;
  33. import javax.management.ObjectName;
  34. import javax.naming.InitialContext;
  35. import javax.transaction.Transaction;
  36. import javax.transaction.TransactionManager;
  37. import javax.net.SocketFactory;
  38. import javax.net.ServerSocketFactory;
  39. import org.jboss.bootstrap.spi.util.ServerConfigUtil;
  40. import org.jboss.invocation.Invocation;
  41. import org.jboss.invocation.pooled.interfaces.PooledInvokerProxy;
  42. import org.jboss.invocation.pooled.interfaces.ServerAddress;
  43. import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation;
  44. import org.jboss.logging.Logger;
  45. import org.jboss.proxy.TransactionInterceptor;
  46. import org.jboss.system.Registry;
  47. import org.jboss.system.ServiceMBeanSupport;
  48. import org.jboss.tm.TransactionPropagationContextFactory;
  49. import org.jboss.tm.TransactionPropagationContextImporter;
  50. import org.jboss.tm.TransactionPropagationContextUtil;
  51. import org.jboss.security.SecurityDomain;
  52. import org.jboss.net.sockets.DefaultSocketFactory;
  53. /**
  54. * This invoker pools Threads and client connections to one server socket.
  55. * The purpose is to avoid a bunch of failings of RMI.
  56. *
  57. * 1. Avoid making a client socket connection with every invocation call.
  58. * This is very expensive. Also on windows if too many clients try
  59. * to connect at the same time, you get connection refused exceptions.
  60. * This invoker/proxy combo alleviates this.
  61. *
  62. * 2. Avoid creating a thread per invocation. The client/server connection
  63. * is preserved and attached to the same thread.
  64. * So we have connection pooling on the server and client side, and thread pooling
  65. * on the server side. Pool, is an LRU pool, so resources should be cleaned up.
  66. *
  67. *
  68. * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
  69. * @author Scott.Stark@jboss.org
  70. * @version $Revision: 81030 $
  71. *
  72. * @jmx:mbean extends="org.jboss.system.ServiceMBean"
  73. */
  74. public class PooledInvoker extends ServiceMBeanSupport
  75. implements PooledInvokerMBean, Runnable
  76. {
  77. /**
  78. * logger instance.
  79. */
  80. final static protected Logger log = Logger.getLogger(PooledInvoker.class);
  81. /**
  82. * If the TcpNoDelay option should be used on the socket.
  83. */
  84. protected boolean enableTcpNoDelay = false;
  85. /**
  86. * The internet address to bind to by default.
  87. */
  88. protected String serverBindAddress = null;
  89. /**
  90. * The server port to bind to.
  91. */
  92. protected int serverBindPort = 0;
  93. /**
  94. * The internet address client will use to connect to the sever.
  95. */
  96. protected String clientConnectAddress = null;
  97. /**
  98. * The port a client will use to connect to the sever.
  99. */
  100. protected int clientConnectPort = 0;
  101. /**
  102. * The number of retry attempts on
  103. */
  104. protected int clientRetryCount = 1;
  105. protected int backlog = 200;
  106. /** The class name of the optional custom client socket factory */
  107. protected String clientSocketFactoryName;
  108. /** The class name of the optional custom server socket factory */
  109. protected String serverSocketFactoryName;
  110. /** An optional custom client socket factory */
  111. protected SocketFactory clientSocketFactory;
  112. /** An optional custom server socket factory */
  113. protected ServerSocketFactory serverSocketFactory;
  114. /** The server socket for */
  115. protected ServerSocket serverSocket = null;
  116. /** The name of the security domain to use with server sockets that support SSL */
  117. protected String sslDomain;
  118. protected int timeout = 60000; // 60 seconds.
  119. protected int maxPoolSize = 300;
  120. protected int clientMaxPoolSize = 300;
  121. protected int numAcceptThreads = 1;
  122. protected Thread[] acceptThreads;
  123. protected LRUPool clientpool;
  124. protected LinkedList threadpool;
  125. protected boolean running = true;
  126. /** The logging trace level flag */
  127. protected boolean trace = false;
  128. /**
  129. * ObjectName of the <code>transactionManagerService</code> we use.
  130. * Probably should not be here -- used to set txInterceptor tx mananger.
  131. */
  132. protected ObjectName transactionManagerService;
  133. protected PooledInvokerProxy optimizedInvokerProxy = null;
  134. /** A priviledged actions for MBeanServer.invoke when running with sec mgr */
  135. private MBeanServerAction serverAction = new MBeanServerAction();
  136. protected static TransactionPropagationContextFactory tpcFactory;
  137. protected static TransactionPropagationContextImporter tpcImporter;
  138. ////////////////////////////////////////////////////////////////////////
  139. //
  140. // The following methods Override the ServiceMBeanSupport base class
  141. //
  142. ////////////////////////////////////////////////////////////////////////
  143. protected void jmxBind()
  144. {
  145. Registry.bind(getServiceName(), optimizedInvokerProxy);
  146. }
  147. /**
  148. * Starts this IL, and binds it to JNDI
  149. *
  150. * @exception Exception Description of Exception
  151. */
  152. public void startService() throws Exception
  153. {
  154. trace = log.isTraceEnabled();
  155. ///////////////////////////////////////////////////////////
  156. // Setup the transaction stuff
  157. ///////////////////////////////////////////////////////////
  158. InitialContext ctx = new InitialContext();
  159. // Get the transaction propagation context factory
  160. tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
  161. // and the transaction propagation context importer
  162. tpcImporter = TransactionPropagationContextUtil.getTPCImporter();
  163. // FIXME marcf: This should not be here
  164. TransactionInterceptor.setTransactionManager((TransactionManager)ctx.lookup("java:/TransactionManager"));
  165. ///////////////////////////////////////////////////////////
  166. // Setup the socket level stuff
  167. ///////////////////////////////////////////////////////////
  168. InetAddress bindAddress =
  169. (serverBindAddress == null || serverBindAddress.length() == 0)
  170. ? null
  171. : InetAddress.getByName(serverBindAddress);
  172. clientConnectAddress =
  173. (clientConnectAddress == null || clientConnectAddress.length() == 0)
  174. ? InetAddress.getLocalHost().getHostName()
  175. : clientConnectAddress;
  176. /* We need to check the address against "0.0.0.0" as this is not a valid
  177. address although some jdks will default to the host, while others fail
  178. with java.net.BindException: Cannot assign requested address: connect
  179. */
  180. clientConnectAddress = ServerConfigUtil.fixRemoteAddress(clientConnectAddress);
  181. // Load any custom socket factories
  182. loadCustomSocketFactories();
  183. clientpool = new LRUPool(2, maxPoolSize);
  184. clientpool.create();
  185. threadpool = new LinkedList();
  186. try
  187. {
  188. if( serverSocketFactory != null )
  189. serverSocket = serverSocketFactory.createServerSocket(serverBindPort, backlog, bindAddress);
  190. else
  191. serverSocket = new ServerSocket(serverBindPort, backlog, bindAddress);
  192. }
  193. catch( java.net.BindException be)
  194. {
  195. throw new Exception("Port "+serverBindPort+" is already in use",be);
  196. }
  197. serverBindPort = serverSocket.getLocalPort();
  198. clientConnectPort = (clientConnectPort == 0) ? serverSocket.getLocalPort() : clientConnectPort;
  199. ServerAddress sa = new ServerAddress(clientConnectAddress, clientConnectPort,
  200. enableTcpNoDelay, timeout, clientSocketFactory);
  201. optimizedInvokerProxy = new PooledInvokerProxy(sa, clientMaxPoolSize, clientRetryCount);
  202. ///////////////////////////////////////////////////////////
  203. // Register the service with the rest of the JBoss Kernel
  204. ///////////////////////////////////////////////////////////
  205. // Export references to the bean
  206. jmxBind();
  207. log.debug("Bound invoker for JMX node");
  208. ctx.close();
  209. acceptThreads = new Thread[numAcceptThreads];
  210. for (int i = 0; i < numAcceptThreads; i++)
  211. {
  212. String name = "PooledInvokerAcceptor#"+i+"-"+serverBindPort;
  213. acceptThreads[i] = new Thread(this, name);
  214. acceptThreads[i].start();
  215. }
  216. }
  217. public void run()
  218. {
  219. while (running)
  220. {
  221. try
  222. {
  223. Socket socket = serverSocket.accept();
  224. if( trace )
  225. log.trace("Accepted: "+socket);
  226. ServerThread thread = null;
  227. boolean newThread = false;
  228. while (thread == null)
  229. {
  230. synchronized(threadpool)
  231. {
  232. if (threadpool.size() > 0)
  233. {
  234. thread = (ServerThread)threadpool.removeFirst();
  235. }
  236. }
  237. if (thread == null)
  238. {
  239. synchronized(clientpool)
  240. {
  241. if (clientpool.size() < maxPoolSize)
  242. {
  243. thread = new ServerThread(socket, this, clientpool, threadpool, timeout);
  244. newThread = true;
  245. }
  246. if (thread == null)
  247. {
  248. clientpool.evict();
  249. if( trace )
  250. log.trace("Waiting for a thread...");
  251. clientpool.wait();
  252. if( trace )
  253. log.trace("Notified of available thread");
  254. }
  255. }
  256. }
  257. }
  258. synchronized(clientpool)
  259. {
  260. clientpool.insert(thread, thread);
  261. }
  262. if (newThread)
  263. {
  264. if( trace )
  265. log.trace("Created a new thread, t="+thread);
  266. thread.start();
  267. }
  268. else
  269. {
  270. if( trace )
  271. log.trace("Reusing thread t="+thread);
  272. thread.wakeup(socket, timeout);
  273. }
  274. }
  275. catch (Throwable ex)
  276. {
  277. if (running)
  278. log.error("Failed to accept socket connection", ex);
  279. }
  280. }
  281. }
  282. /**
  283. * Stops this service, and unbinds it from JNDI.
  284. */
  285. public void stopService() throws Exception
  286. {
  287. running = false;
  288. maxPoolSize = 0; // so ServerThreads don't reinsert themselves
  289. for (int i = 0; i < acceptThreads.length; i++)
  290. {
  291. try
  292. {
  293. acceptThreads[i].interrupt();
  294. }
  295. catch (Exception ignored){}
  296. }
  297. clientpool.flush();
  298. for (int i = 0; i < threadpool.size(); i++)
  299. {
  300. ServerThread thread = (ServerThread)threadpool.removeFirst();
  301. thread.shutdown();
  302. }
  303. try
  304. {
  305. serverSocket.close();
  306. }
  307. catch(Exception e)
  308. {
  309. }
  310. }
  311. protected void destroyService() throws Exception
  312. {
  313. // Unexport references to the bean
  314. Registry.unbind(getServiceName());
  315. }
  316. /**
  317. * The ServerProtocol will use this method to service an invocation
  318. * request.
  319. */
  320. public Object invoke(Invocation invocation) throws Exception
  321. {
  322. Thread currentThread = Thread.currentThread();
  323. ClassLoader oldCl = currentThread.getContextClassLoader();
  324. try
  325. {
  326. // Deserialize the transaction if it is there
  327. PooledMarshalledInvocation mi = (PooledMarshalledInvocation) invocation;
  328. invocation.setTransaction(importTPC(mi.getTransactionPropagationContext()));
  329. ObjectName mbean = (ObjectName) Registry.lookup(invocation.getObjectName());
  330. if( mbean == null )
  331. {
  332. System.err.println("NoSuchObjectException: "+invocation.getObjectName());
  333. throw new NoSuchObjectException("Failed to find target for objectName: "+invocation.getObjectName());
  334. }
  335. // The cl on the thread should be set in another interceptor
  336. Object obj = serverAction.invoke(mbean, "invoke",
  337. new Object[] { invocation }, Invocation.INVOKE_SIGNATURE);
  338. return obj;
  339. }
  340. catch (Exception e)
  341. {
  342. org.jboss.mx.util.JMXExceptionDecoder.rethrow(e);
  343. // the compiler does not know an exception is thrown by the above
  344. throw new org.jboss.util.UnreachableStatementException();
  345. }
  346. finally
  347. {
  348. currentThread.setContextClassLoader(oldCl);
  349. }
  350. }
  351. protected Transaction importTPC(Object tpc)
  352. {
  353. if (tpc != null)
  354. return tpcImporter.importTransactionPropagationContext(tpc);
  355. return null;
  356. }
  357. //The following are the mbean attributes for TrunkInvoker
  358. /**
  359. * Getter for property numAcceptThreads
  360. *
  361. * @return Value of property numAcceptThreads
  362. * @jmx:managed-attribute
  363. */
  364. public int getNumAcceptThreads()
  365. {
  366. return numAcceptThreads;
  367. }
  368. /**
  369. * Setter for property numAcceptThreads
  370. *
  371. * @param size New value of property numAcceptThreads.
  372. * @jmx:managed-attribute
  373. */
  374. public void setNumAcceptThreads(int size)
  375. {
  376. this.numAcceptThreads = size;
  377. }
  378. /**
  379. * Getter for property maxPoolSize;
  380. *
  381. * @return Value of property maxPoolSize.
  382. * @jmx:managed-attribute
  383. */
  384. public int getMaxPoolSize()
  385. {
  386. return maxPoolSize;
  387. }
  388. /**
  389. * Setter for property maxPoolSize.
  390. *
  391. * @param maxPoolSize New value of property maxPoolSize.
  392. * @jmx:managed-attribute
  393. */
  394. public void setMaxPoolSize(int maxPoolSize)
  395. {
  396. this.maxPoolSize = maxPoolSize;
  397. }
  398. /**
  399. * Getter for property maxPoolSize;
  400. *
  401. * @return Value of property maxPoolSize.
  402. * @jmx:managed-attribute
  403. */
  404. public int getClientMaxPoolSize()
  405. {
  406. return clientMaxPoolSize;
  407. }
  408. /**
  409. * Setter for property maxPoolSize.
  410. *
  411. * @param clientMaxPoolSize New value of property serverBindPort.
  412. * @jmx:managed-attribute
  413. */
  414. public void setClientMaxPoolSize(int clientMaxPoolSize)
  415. {
  416. this.clientMaxPoolSize = clientMaxPoolSize;
  417. }
  418. /**
  419. * Getter for property timeout
  420. *
  421. * @return Value of property timeout
  422. * @jmx:managed-attribute
  423. */
  424. public int getSocketTimeout()
  425. {
  426. return timeout;
  427. }
  428. /**
  429. * Setter for property timeout
  430. *
  431. * @param time New value of property timeout
  432. * @jmx:managed-attribute
  433. */
  434. public void setSocketTimeout(int time)
  435. {
  436. this.timeout = time;
  437. }
  438. /**
  439. *
  440. * @return Value of property CurrentClientPoolSize.
  441. * @jmx:managed-attribute
  442. */
  443. public int getCurrentClientPoolSize()
  444. {
  445. return clientpool.size();
  446. }
  447. /**
  448. *
  449. * @return Value of property CurrentThreadPoolSize.
  450. * @jmx:managed-attribute
  451. */
  452. public int getCurrentThreadPoolSize()
  453. {
  454. return threadpool.size();
  455. }
  456. /**
  457. * Getter for property serverBindPort.
  458. *
  459. * @return Value of property serverBindPort.
  460. * @jmx:managed-attribute
  461. */
  462. public int getServerBindPort()
  463. {
  464. return serverBindPort;
  465. }
  466. /**
  467. * Setter for property serverBindPort.
  468. *
  469. * @param serverBindPort New value of property serverBindPort.
  470. * @jmx:managed-attribute
  471. */
  472. public void setServerBindPort(int serverBindPort)
  473. {
  474. this.serverBindPort = serverBindPort;
  475. }
  476. /**
  477. * @jmx:managed-attribute
  478. */
  479. public String getClientConnectAddress()
  480. {
  481. return clientConnectAddress;
  482. }
  483. /**
  484. * @jmx:managed-attribute
  485. */
  486. public void setClientConnectAddress(String clientConnectAddress)
  487. {
  488. this.clientConnectAddress = clientConnectAddress;
  489. }
  490. /**
  491. * @jmx:managed-attribute
  492. */
  493. public int getClientConnectPort()
  494. {
  495. return clientConnectPort;
  496. }
  497. /**
  498. * @jmx:managed-attribute
  499. */
  500. public void setClientConnectPort(int clientConnectPort)
  501. {
  502. this.clientConnectPort = clientConnectPort;
  503. }
  504. /**
  505. * @jmx:managed-attribute
  506. */
  507. public int getClientRetryCount()
  508. {
  509. return clientRetryCount;
  510. }
  511. /**
  512. * @jmx:managed-attribute
  513. */
  514. public void setClientRetryCount(int clientRetryCount)
  515. {
  516. this.clientRetryCount = clientRetryCount;
  517. }
  518. /**
  519. * @jmx:managed-attribute
  520. */
  521. public int getBacklog()
  522. {
  523. return backlog;
  524. }
  525. /**
  526. * @jmx:managed-attribute
  527. */
  528. public void setBacklog(int backlog)
  529. {
  530. this.backlog = backlog;
  531. }
  532. /**
  533. * @jmx:managed-attribute
  534. */
  535. public boolean isEnableTcpNoDelay()
  536. {
  537. return enableTcpNoDelay;
  538. }
  539. /**
  540. * @jmx:managed-attribute
  541. */
  542. public void setEnableTcpNoDelay(boolean enableTcpNoDelay)
  543. {
  544. this.enableTcpNoDelay = enableTcpNoDelay;
  545. }
  546. /**
  547. * @jmx:managed-attribute
  548. */
  549. public String getServerBindAddress()
  550. {
  551. return serverBindAddress;
  552. }
  553. /**
  554. * @jmx:managed-attribute
  555. */
  556. public void setServerBindAddress(String serverBindAddress)
  557. {
  558. this.serverBindAddress = serverBindAddress;
  559. }
  560. /**
  561. * @jmx:managed-attribute
  562. */
  563. public String getClientSocketFactoryName()
  564. {
  565. return clientSocketFactoryName;
  566. }
  567. /**
  568. * @jmx:managed-attribute
  569. */
  570. public void setClientSocketFactoryName(String clientSocketFactoryName)
  571. {
  572. this.clientSocketFactoryName = clientSocketFactoryName;
  573. }
  574. /**
  575. * @jmx:managed-attribute
  576. */
  577. public String getServerSocketFactoryName()
  578. {
  579. return serverSocketFactoryName;
  580. }
  581. /**
  582. * @jmx:managed-attribute
  583. */
  584. public void setServerSocketFactoryName(String serverSocketFactoryName)
  585. {
  586. this.serverSocketFactoryName = serverSocketFactoryName;
  587. }
  588. /**
  589. * @jmx:managed-attribute
  590. */
  591. public SocketFactory getClientSocketFactory()
  592. {
  593. return clientSocketFactory;
  594. }
  595. /**
  596. * @jmx:managed-attribute
  597. */
  598. public void setClientSocketFactory(SocketFactory clientSocketFactory)
  599. {
  600. this.clientSocketFactory = clientSocketFactory;
  601. }
  602. /**
  603. * @jmx:managed-attribute
  604. */
  605. public ServerSocket getServerSocket()
  606. {
  607. return serverSocket;
  608. }
  609. /**
  610. * @jmx:managed-attribute
  611. */
  612. public void setServerSocket(ServerSocket serverSocket)
  613. {
  614. this.serverSocket = serverSocket;
  615. }
  616. /**
  617. * @jmx:managed-attribute
  618. */
  619. public String getSslDomain()
  620. {
  621. return sslDomain;
  622. }
  623. /**
  624. * @jmx:managed-attribute
  625. */
  626. public void setSslDomain(String sslDomain)
  627. {
  628. this.sslDomain = sslDomain;
  629. }
  630. /**
  631. * @jmx:managed-attribute
  632. */
  633. public ServerSocketFactory getServerSocketFactory()
  634. {
  635. return serverSocketFactory;
  636. }
  637. /**
  638. * @jmx:managed-attribute
  639. */
  640. public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)
  641. {
  642. this.serverSocketFactory = serverSocketFactory;
  643. }
  644. /**
  645. * mbean get-set pair for field transactionManagerService
  646. * Get the value of transactionManagerService
  647. * @return value of transactionManagerService
  648. *
  649. * @jmx:managed-attribute
  650. */
  651. public ObjectName getTransactionManagerService()
  652. {
  653. return transactionManagerService;
  654. }
  655. /**
  656. * Set the value of transactionManagerService
  657. * @param transactionManagerService Value to assign to transactionManagerService
  658. *
  659. * @jmx:managed-attribute
  660. */
  661. public void setTransactionManagerService(ObjectName transactionManagerService)
  662. {
  663. this.transactionManagerService = transactionManagerService;
  664. }
  665. /**
  666. * @jmx:managed-attribute
  667. */
  668. public PooledInvokerProxy getOptimizedInvokerProxy()
  669. {
  670. return optimizedInvokerProxy;
  671. }
  672. /** Load and instantiate the clientSocketFactory, serverSocketFactory using
  673. the TCL and set the bind address and SSL domain if the serverSocketFactory
  674. supports it.
  675. */
  676. protected void loadCustomSocketFactories()
  677. {
  678. ClassLoader loader = Thread.currentThread().getContextClassLoader();
  679. try
  680. {
  681. if( clientSocketFactoryName != null )
  682. {
  683. Class csfClass = loader.loadClass(clientSocketFactoryName);
  684. clientSocketFactory = (SocketFactory) csfClass.newInstance();
  685. }
  686. }
  687. catch (Exception e)
  688. {
  689. log.error("Failed to load client socket factory", e);
  690. clientSocketFactory = null;
  691. }
  692. try
  693. {
  694. if( serverSocketFactory == null )
  695. {
  696. if( serverSocketFactoryName != null )
  697. {
  698. Class ssfClass = loader.loadClass(serverSocketFactoryName);
  699. serverSocketFactory = (ServerSocketFactory) ssfClass.newInstance();
  700. if( serverBindAddress != null )
  701. {
  702. // See if the server socket supports setBindAddress(String)
  703. try
  704. {
  705. Class[] parameterTypes = {String.class};
  706. Method m = ssfClass.getMethod("setBindAddress", parameterTypes);
  707. Object[] args = {serverBindAddress};
  708. m.invoke(serverSocketFactory, args);
  709. }
  710. catch (NoSuchMethodException e)
  711. {
  712. log.warn("Socket factory does not support setBindAddress(String)");
  713. // Go with default address
  714. }
  715. catch (Exception e)
  716. {
  717. log.warn("Failed to setBindAddress="+serverBindAddress+" on socket factory", e);
  718. // Go with default address
  719. }
  720. }
  721. /* See if the server socket supports setSecurityDomain(SecurityDomain)
  722. if an sslDomain was specified
  723. */
  724. if( sslDomain != null )
  725. {
  726. try
  727. {
  728. InitialContext ctx = new InitialContext();
  729. SecurityDomain domain = (SecurityDomain) ctx.lookup(sslDomain);
  730. Class[] parameterTypes = {SecurityDomain.class};
  731. Method m = ssfClass.getMethod("setSecurityDomain", parameterTypes);
  732. Object[] args = {domain};
  733. m.invoke(serverSocketFactory, args);
  734. }
  735. catch(NoSuchMethodException e)
  736. {
  737. log.error("Socket factory does not support setSecurityDomain(SecurityDomain)");
  738. }
  739. catch(Exception e)
  740. {
  741. log.error("Failed to setSecurityDomain="+sslDomain+" on socket factory", e);
  742. }
  743. }
  744. }
  745. // If a bind address was specified create a DefaultSocketFactory
  746. else if( serverBindAddress != null )
  747. {
  748. DefaultSocketFactory defaultFactory = new DefaultSocketFactory(backlog);
  749. serverSocketFactory = defaultFactory;
  750. try
  751. {
  752. defaultFactory.setBindAddress(serverBindAddress);
  753. }
  754. catch (UnknownHostException e)
  755. {
  756. log.error("Failed to setBindAddress="+serverBindAddress+" on socket factory", e);
  757. }
  758. }
  759. }
  760. }
  761. catch (Exception e)
  762. {
  763. log.error("operation failed", e);
  764. serverSocketFactory = null;
  765. }
  766. }
  767. /** Perform the MBeanServer.invoke op in a PrivilegedExceptionAction if
  768. * running with a security manager.
  769. */
  770. class MBeanServerAction implements PrivilegedExceptionAction
  771. {
  772. private ObjectName target;
  773. String method;
  774. Object[] args;
  775. String[] sig;
  776. MBeanServerAction()
  777. {
  778. }
  779. MBeanServerAction(ObjectName target, String method, Object[] args, String[] sig)
  780. {
  781. this.target = target;
  782. this.method = method;
  783. this.args = args;
  784. this.sig = sig;
  785. }
  786. public Object run() throws Exception
  787. {
  788. Object rtnValue = server.invoke(target, method, args, sig);
  789. return rtnValue;
  790. }
  791. Object invoke(ObjectName target, String method, Object[] args, String[] sig)
  792. throws Exception
  793. {
  794. SecurityManager sm = System.getSecurityManager();
  795. Object rtnValue = null;
  796. if( sm == null )
  797. {
  798. // Direct invocation on MBeanServer
  799. rtnValue = server.invoke(target, method, args, sig);
  800. }
  801. else
  802. {
  803. try
  804. {
  805. // Encapsulate the invocation in a PrivilegedExceptionAction
  806. MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
  807. rtnValue = AccessController.doPrivileged(action);
  808. }
  809. catch (PrivilegedActionException e)
  810. {
  811. Exception ex = e.getException();
  812. throw ex;
  813. }
  814. }
  815. return rtnValue;
  816. }
  817. }
  818. }
  819. // vim:expandtab:tabstop=3:shiftwidth=3