Package org.jboss.invocation.pooled.server

Source Code of org.jboss.invocation.pooled.server.PooledInvoker$MBeanServerAction

/*     */ package org.jboss.invocation.pooled.server;
/*     */
/*     */ import java.io.PrintStream;
/*     */ import java.lang.reflect.Method;
/*     */ import java.net.BindException;
/*     */ import java.net.InetAddress;
/*     */ import java.net.ServerSocket;
/*     */ import java.net.Socket;
/*     */ import java.net.UnknownHostException;
/*     */ import java.rmi.NoSuchObjectException;
/*     */ import java.security.AccessController;
/*     */ import java.security.PrivilegedActionException;
/*     */ import java.security.PrivilegedExceptionAction;
/*     */ import java.util.LinkedList;
/*     */ import javax.management.MBeanServer;
/*     */ import javax.management.ObjectName;
/*     */ import javax.naming.InitialContext;
/*     */ import javax.net.ServerSocketFactory;
/*     */ import javax.net.SocketFactory;
/*     */ import javax.transaction.Transaction;
/*     */ import javax.transaction.TransactionManager;
/*     */ import org.jboss.invocation.Invocation;
/*     */ import org.jboss.invocation.pooled.interfaces.PooledInvokerProxy;
/*     */ import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation;
/*     */ import org.jboss.invocation.pooled.interfaces.ServerAddress;
/*     */ import org.jboss.logging.Logger;
/*     */ import org.jboss.mx.util.JMXExceptionDecoder;
/*     */ import org.jboss.net.sockets.DefaultSocketFactory;
/*     */ import org.jboss.proxy.TransactionInterceptor;
/*     */ import org.jboss.security.SecurityDomain;
/*     */ import org.jboss.system.Registry;
/*     */ import org.jboss.system.ServiceMBeanSupport;
/*     */ import org.jboss.system.server.ServerConfigUtil;
/*     */ import org.jboss.tm.TransactionPropagationContextFactory;
/*     */ import org.jboss.tm.TransactionPropagationContextImporter;
/*     */ import org.jboss.tm.TransactionPropagationContextUtil;
/*     */ import org.jboss.util.UnreachableStatementException;
/*     */
/*     */ public class PooledInvoker extends ServiceMBeanSupport
/*     */   implements PooledInvokerMBean, Runnable
/*     */ {
/*  85 */   protected static final Logger log = Logger.getLogger(PooledInvoker.class);
/*     */   protected boolean enableTcpNoDelay;
/*     */   protected String serverBindAddress;
/*     */   protected int serverBindPort;
/*     */   protected String clientConnectAddress;
/*     */   protected int clientConnectPort;
/*     */   protected int clientRetryCount;
/*     */   protected int backlog;
/*     */   protected String clientSocketFactoryName;
/*     */   protected String serverSocketFactoryName;
/*     */   protected SocketFactory clientSocketFactory;
/*     */   protected ServerSocketFactory serverSocketFactory;
/*     */   protected ServerSocket serverSocket;
/*     */   protected String sslDomain;
/*     */   protected int timeout;
/*     */   protected int maxPoolSize;
/*     */   protected int clientMaxPoolSize;
/*     */   protected int numAcceptThreads;
/*     */   protected Thread[] acceptThreads;
/*     */   protected LRUPool clientpool;
/*     */   protected LinkedList threadpool;
/*     */   protected boolean running;
/*     */   protected boolean trace;
/*     */   protected ObjectName transactionManagerService;
/*     */   protected PooledInvokerProxy optimizedInvokerProxy;
/*     */   private MBeanServerAction serverAction;
/*     */   protected static TransactionPropagationContextFactory tpcFactory;
/*     */   protected static TransactionPropagationContextImporter tpcImporter;
/*     */
/*     */   public PooledInvoker()
/*     */   {
/*  90 */     this.enableTcpNoDelay = false;
/*     */
/*  95 */     this.serverBindAddress = null;
/*     */
/* 100 */     this.serverBindPort = 0;
/*     */
/* 105 */     this.clientConnectAddress = null;
/*     */
/* 110 */     this.clientConnectPort = 0;
/*     */
/* 114 */     this.clientRetryCount = 1;
/*     */
/* 116 */     this.backlog = 200;
/*     */
/* 130 */     this.serverSocket = null;
/*     */
/* 135 */     this.timeout = 60000;
/*     */
/* 137 */     this.maxPoolSize = 300;
/*     */
/* 139 */     this.clientMaxPoolSize = 300;
/*     */
/* 141 */     this.numAcceptThreads = 1;
/*     */
/* 146 */     this.running = true;
/*     */
/* 148 */     this.trace = false;
/*     */
/* 155 */     this.optimizedInvokerProxy = null;
/*     */
/* 157 */     this.serverAction = new MBeanServerAction();
/*     */   }
/*     */
/*     */   protected void jmxBind()
/*     */   {
/* 170 */     Registry.bind(getServiceName(), this.optimizedInvokerProxy);
/*     */   }
/*     */
/*     */   public void startService()
/*     */     throws Exception
/*     */   {
/* 180 */     this.trace = log.isTraceEnabled();
/*     */
/* 185 */     InitialContext ctx = new InitialContext();
/*     */
/* 188 */     tpcFactory = TransactionPropagationContextUtil.getTPCFactory();
/*     */
/* 191 */     tpcImporter = TransactionPropagationContextUtil.getTPCImporter();
/*     */
/* 194 */     TransactionInterceptor.setTransactionManager((TransactionManager)ctx.lookup("java:/TransactionManager"));
/*     */
/* 200 */     InetAddress bindAddress = (this.serverBindAddress == null) || (this.serverBindAddress.length() == 0) ? null : InetAddress.getByName(this.serverBindAddress);
/*     */
/* 205 */     this.clientConnectAddress = ((this.clientConnectAddress == null) || (this.clientConnectAddress.length() == 0) ? InetAddress.getLocalHost().getHostName() : this.clientConnectAddress);
/*     */
/* 213 */     this.clientConnectAddress = ServerConfigUtil.fixRemoteAddress(this.clientConnectAddress);
/*     */
/* 216 */     loadCustomSocketFactories();
/*     */
/* 218 */     this.clientpool = new LRUPool(2, this.maxPoolSize);
/* 219 */     this.clientpool.create();
/* 220 */     this.threadpool = new LinkedList();
/*     */     try
/*     */     {
/* 223 */       if (this.serverSocketFactory != null)
/* 224 */         this.serverSocket = this.serverSocketFactory.createServerSocket(this.serverBindPort, this.backlog, bindAddress);
/*     */       else
/* 226 */         this.serverSocket = new ServerSocket(this.serverBindPort, this.backlog, bindAddress);
/*     */     }
/*     */     catch (BindException be)
/*     */     {
/* 230 */       throw new Exception("Port " + this.serverBindPort + " is already in use", be);
/*     */     }
/* 232 */     this.serverBindPort = this.serverSocket.getLocalPort();
/* 233 */     this.clientConnectPort = (this.clientConnectPort == 0 ? this.serverSocket.getLocalPort() : this.clientConnectPort);
/*     */
/* 235 */     ServerAddress sa = new ServerAddress(this.clientConnectAddress, this.clientConnectPort, this.enableTcpNoDelay, this.timeout, this.clientSocketFactory);
/*     */
/* 237 */     this.optimizedInvokerProxy = new PooledInvokerProxy(sa, this.clientMaxPoolSize, this.clientRetryCount);
/*     */
/* 243 */     jmxBind();
/* 244 */     log.debug("Bound invoker for JMX node");
/* 245 */     ctx.close();
/*     */
/* 247 */     this.acceptThreads = new Thread[this.numAcceptThreads];
/* 248 */     for (int i = 0; i < this.numAcceptThreads; i++)
/*     */     {
/* 250 */       String name = "PooledInvokerAcceptor#" + i + "-" + this.serverBindPort;
/* 251 */       this.acceptThreads[i] = new Thread(this, name);
/* 252 */       this.acceptThreads[i].start();
/*     */     }
/*     */   }
/*     */
/*     */   public void run()
/*     */   {
/* 258 */     while (this.running)
/*     */     {
/*     */       try
/*     */       {
/* 262 */         Socket socket = this.serverSocket.accept();
/* 263 */         if (this.trace)
/* 264 */           log.trace("Accepted: " + socket);
/* 265 */         ServerThread thread = null;
/* 266 */         boolean newThread = false;
/*     */
/* 268 */         while (thread == null)
/*     */         {
/* 270 */           synchronized (this.threadpool)
/*     */           {
/* 272 */             if (this.threadpool.size() > 0)
/*     */             {
/* 274 */               thread = (ServerThread)this.threadpool.removeFirst();
/*     */             }
/*     */           }
/* 277 */           if (thread != null)
/*     */             continue;
/* 279 */           synchronized (this.clientpool)
/*     */           {
/* 281 */             if (this.clientpool.size() < this.maxPoolSize)
/*     */             {
/* 283 */               thread = new ServerThread(socket, this, this.clientpool, this.threadpool, this.timeout);
/* 284 */               newThread = true;
/*     */             }
/* 286 */             if (thread == null)
/*     */             {
/* 288 */               this.clientpool.evict();
/* 289 */               if (this.trace)
/* 290 */                 log.trace("Waiting for a thread...");
/* 291 */               this.clientpool.wait();
/* 292 */               if (this.trace) {
/* 293 */                 log.trace("Notified of available thread");
/*     */               }
/*     */             }
/*     */           }
/*     */         }
/* 298 */         synchronized (this.clientpool)
/*     */         {
/* 300 */           this.clientpool.insert(thread, thread);
/*     */         }
/*     */
/* 303 */         if (newThread)
/*     */         {
/* 305 */           if (this.trace)
/* 306 */             log.trace("Created a new thread, t=" + thread);
/* 307 */           thread.start();
/*     */         }
/*     */         else
/*     */         {
/* 311 */           if (this.trace)
/* 312 */             log.trace("Reusing thread t=" + thread);
/* 313 */           thread.wakeup(socket, this.timeout);
/*     */         }
/*     */       }
/*     */       catch (Throwable ex)
/*     */       {
/* 318 */         if (this.running)
/* 319 */           log.error("Failed to accept socket connection", ex);
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   public void stopService()
/*     */     throws Exception
/*     */   {
/* 329 */     this.running = false;
/* 330 */     this.maxPoolSize = 0;
/* 331 */     for (int i = 0; i < this.acceptThreads.length; i++)
/*     */     {
/*     */       try
/*     */       {
/* 335 */         this.acceptThreads[i].interrupt();
/*     */       } catch (Exception ignored) {
/*     */       }
/*     */     }
/* 339 */     this.clientpool.flush();
/* 340 */     for (int i = 0; i < this.threadpool.size(); i++)
/*     */     {
/* 342 */       ServerThread thread = (ServerThread)this.threadpool.removeFirst();
/* 343 */       thread.shutdown();
/*     */     }
/*     */
/*     */     try
/*     */     {
/* 348 */       this.serverSocket.close();
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/*     */     }
/*     */   }
/*     */
/*     */   protected void destroyService()
/*     */     throws Exception
/*     */   {
/* 358 */     Registry.unbind(getServiceName());
/*     */   }
/*     */
/*     */   public Object invoke(Invocation invocation)
/*     */     throws Exception
/*     */   {
/* 367 */     Thread currentThread = Thread.currentThread();
/* 368 */     ClassLoader oldCl = currentThread.getContextClassLoader();
/*     */     try
/*     */     {
/* 373 */       PooledMarshalledInvocation mi = (PooledMarshalledInvocation)invocation;
/* 374 */       invocation.setTransaction(importTPC(mi.getTransactionPropagationContext()));
/* 375 */       ObjectName mbean = (ObjectName)Registry.lookup(invocation.getObjectName());
/* 376 */       if (mbean == null)
/*     */       {
/* 378 */         System.err.println("NoSuchObjectException: " + invocation.getObjectName());
/* 379 */         throw new NoSuchObjectException("Failed to find target for objectName: " + invocation.getObjectName());
/*     */       }
/*     */
/* 383 */       Object obj = this.serverAction.invoke(mbean, "invoke", new Object[] { invocation }, Invocation.INVOKE_SIGNATURE);
/*     */
/* 386 */       localObject1 = obj;
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/*     */       Object localObject1;
/* 390 */       JMXExceptionDecoder.rethrow(e);
/*     */
/* 393 */       throw new UnreachableStatementException();
/*     */     }
/*     */     finally
/*     */     {
/* 397 */       currentThread.setContextClassLoader(oldCl);
/*     */     }
/*     */   }
/*     */
/*     */   protected Transaction importTPC(Object tpc)
/*     */   {
/* 403 */     if (tpc != null)
/* 404 */       return tpcImporter.importTransactionPropagationContext(tpc);
/* 405 */     return null;
/*     */   }
/*     */
/*     */   public int getNumAcceptThreads()
/*     */   {
/* 418 */     return this.numAcceptThreads;
/*     */   }
/*     */
/*     */   public void setNumAcceptThreads(int size)
/*     */   {
/* 429 */     this.numAcceptThreads = size;
/*     */   }
/*     */
/*     */   public int getMaxPoolSize()
/*     */   {
/* 440 */     return this.maxPoolSize;
/*     */   }
/*     */
/*     */   public void setMaxPoolSize(int maxPoolSize)
/*     */   {
/* 451 */     this.maxPoolSize = maxPoolSize;
/*     */   }
/*     */
/*     */   public int getClientMaxPoolSize()
/*     */   {
/* 462 */     return this.clientMaxPoolSize;
/*     */   }
/*     */
/*     */   public void setClientMaxPoolSize(int clientMaxPoolSize)
/*     */   {
/* 473 */     this.clientMaxPoolSize = clientMaxPoolSize;
/*     */   }
/*     */
/*     */   public int getSocketTimeout()
/*     */   {
/* 484 */     return this.timeout;
/*     */   }
/*     */
/*     */   public void setSocketTimeout(int time)
/*     */   {
/* 495 */     this.timeout = time;
/*     */   }
/*     */
/*     */   public int getCurrentClientPoolSize()
/*     */   {
/* 505 */     return this.clientpool.size();
/*     */   }
/*     */
/*     */   public int getCurrentThreadPoolSize()
/*     */   {
/* 515 */     return this.threadpool.size();
/*     */   }
/*     */
/*     */   public int getServerBindPort()
/*     */   {
/* 526 */     return this.serverBindPort;
/*     */   }
/*     */
/*     */   public void setServerBindPort(int serverBindPort)
/*     */   {
/* 537 */     this.serverBindPort = serverBindPort;
/*     */   }
/*     */
/*     */   public String getClientConnectAddress()
/*     */   {
/* 545 */     return this.clientConnectAddress;
/*     */   }
/*     */
/*     */   public void setClientConnectAddress(String clientConnectAddress)
/*     */   {
/* 553 */     this.clientConnectAddress = clientConnectAddress;
/*     */   }
/*     */
/*     */   public int getClientConnectPort()
/*     */   {
/* 561 */     return this.clientConnectPort;
/*     */   }
/*     */
/*     */   public void setClientConnectPort(int clientConnectPort)
/*     */   {
/* 569 */     this.clientConnectPort = clientConnectPort;
/*     */   }
/*     */
/*     */   public int getClientRetryCount()
/*     */   {
/* 577 */     return this.clientRetryCount;
/*     */   }
/*     */
/*     */   public void setClientRetryCount(int clientRetryCount)
/*     */   {
/* 585 */     this.clientRetryCount = clientRetryCount;
/*     */   }
/*     */
/*     */   public int getBacklog()
/*     */   {
/* 593 */     return this.backlog;
/*     */   }
/*     */
/*     */   public void setBacklog(int backlog)
/*     */   {
/* 601 */     this.backlog = backlog;
/*     */   }
/*     */
/*     */   public boolean isEnableTcpNoDelay()
/*     */   {
/* 609 */     return this.enableTcpNoDelay;
/*     */   }
/*     */
/*     */   public void setEnableTcpNoDelay(boolean enableTcpNoDelay)
/*     */   {
/* 617 */     this.enableTcpNoDelay = enableTcpNoDelay;
/*     */   }
/*     */
/*     */   public String getServerBindAddress()
/*     */   {
/* 625 */     return this.serverBindAddress;
/*     */   }
/*     */
/*     */   public void setServerBindAddress(String serverBindAddress)
/*     */   {
/* 633 */     this.serverBindAddress = serverBindAddress;
/*     */   }
/*     */
/*     */   public String getClientSocketFactoryName()
/*     */   {
/* 641 */     return this.clientSocketFactoryName;
/*     */   }
/*     */
/*     */   public void setClientSocketFactoryName(String clientSocketFactoryName)
/*     */   {
/* 649 */     this.clientSocketFactoryName = clientSocketFactoryName;
/*     */   }
/*     */
/*     */   public String getServerSocketFactoryName()
/*     */   {
/* 657 */     return this.serverSocketFactoryName;
/*     */   }
/*     */
/*     */   public void setServerSocketFactoryName(String serverSocketFactoryName)
/*     */   {
/* 665 */     this.serverSocketFactoryName = serverSocketFactoryName;
/*     */   }
/*     */
/*     */   public SocketFactory getClientSocketFactory()
/*     */   {
/* 673 */     return this.clientSocketFactory;
/*     */   }
/*     */
/*     */   public void setClientSocketFactory(SocketFactory clientSocketFactory)
/*     */   {
/* 681 */     this.clientSocketFactory = clientSocketFactory;
/*     */   }
/*     */
/*     */   public ServerSocket getServerSocket()
/*     */   {
/* 689 */     return this.serverSocket;
/*     */   }
/*     */
/*     */   public void setServerSocket(ServerSocket serverSocket)
/*     */   {
/* 697 */     this.serverSocket = serverSocket;
/*     */   }
/*     */
/*     */   public String getSslDomain()
/*     */   {
/* 705 */     return this.sslDomain;
/*     */   }
/*     */
/*     */   public void setSslDomain(String sslDomain)
/*     */   {
/* 713 */     this.sslDomain = sslDomain;
/*     */   }
/*     */
/*     */   public ServerSocketFactory getServerSocketFactory()
/*     */   {
/* 721 */     return this.serverSocketFactory;
/*     */   }
/*     */
/*     */   public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)
/*     */   {
/* 729 */     this.serverSocketFactory = serverSocketFactory;
/*     */   }
/*     */
/*     */   public ObjectName getTransactionManagerService()
/*     */   {
/* 741 */     return this.transactionManagerService;
/*     */   }
/*     */
/*     */   public void setTransactionManagerService(ObjectName transactionManagerService)
/*     */   {
/* 753 */     this.transactionManagerService = transactionManagerService;
/*     */   }
/*     */
/*     */   public PooledInvokerProxy getOptimizedInvokerProxy()
/*     */   {
/* 761 */     return this.optimizedInvokerProxy;
/*     */   }
/*     */
/*     */   protected void loadCustomSocketFactories()
/*     */   {
/* 770 */     ClassLoader loader = Thread.currentThread().getContextClassLoader();
/*     */     try
/*     */     {
/* 774 */       if (this.clientSocketFactoryName != null)
/*     */       {
/* 776 */         Class csfClass = loader.loadClass(this.clientSocketFactoryName);
/* 777 */         this.clientSocketFactory = ((SocketFactory)csfClass.newInstance());
/*     */       }
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 782 */       log.error("Failed to load client socket factory", e);
/* 783 */       this.clientSocketFactory = null;
/*     */     }
/*     */
/*     */     try
/*     */     {
/* 788 */       if (this.serverSocketFactory == null)
/*     */       {
/* 790 */         if (this.serverSocketFactoryName != null)
/*     */         {
/* 792 */           Class ssfClass = loader.loadClass(this.serverSocketFactoryName);
/* 793 */           this.serverSocketFactory = ((ServerSocketFactory)ssfClass.newInstance());
/* 794 */           if (this.serverBindAddress != null)
/*     */           {
/*     */             try
/*     */             {
/* 799 */               Class[] parameterTypes = { String.class };
/* 800 */               Method m = ssfClass.getMethod("setBindAddress", parameterTypes);
/* 801 */               Object[] args = { this.serverBindAddress };
/* 802 */               m.invoke(this.serverSocketFactory, args);
/*     */             }
/*     */             catch (NoSuchMethodException e)
/*     */             {
/* 806 */               log.warn("Socket factory does not support setBindAddress(String)");
/*     */             }
/*     */             catch (Exception e)
/*     */             {
/* 811 */               log.warn("Failed to setBindAddress=" + this.serverBindAddress + " on socket factory", e);
/*     */             }
/*     */
/*     */           }
/*     */
/* 818 */           if (this.sslDomain != null)
/*     */           {
/*     */             try
/*     */             {
/* 822 */               InitialContext ctx = new InitialContext();
/* 823 */               SecurityDomain domain = (SecurityDomain)ctx.lookup(this.sslDomain);
/* 824 */               Class[] parameterTypes = { SecurityDomain.class };
/* 825 */               Method m = ssfClass.getMethod("setSecurityDomain", parameterTypes);
/* 826 */               Object[] args = { domain };
/* 827 */               m.invoke(this.serverSocketFactory, args);
/*     */             }
/*     */             catch (NoSuchMethodException e)
/*     */             {
/* 831 */               log.error("Socket factory does not support setSecurityDomain(SecurityDomain)");
/*     */             }
/*     */             catch (Exception e)
/*     */             {
/* 835 */               log.error("Failed to setSecurityDomain=" + this.sslDomain + " on socket factory", e);
/*     */             }
/*     */           }
/*     */
/*     */         }
/* 840 */         else if (this.serverBindAddress != null)
/*     */         {
/* 842 */           DefaultSocketFactory defaultFactory = new DefaultSocketFactory(this.backlog);
/* 843 */           this.serverSocketFactory = defaultFactory;
/*     */           try
/*     */           {
/* 846 */             defaultFactory.setBindAddress(this.serverBindAddress);
/*     */           }
/*     */           catch (UnknownHostException e)
/*     */           {
/* 850 */             log.error("Failed to setBindAddress=" + this.serverBindAddress + " on socket factory", e);
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 857 */       log.error("operation failed", e);
/* 858 */       this.serverSocketFactory = null;
/*     */     }
/*     */   }
/*     */
/*     */   class MBeanServerAction implements PrivilegedExceptionAction
/*     */   {
/*     */     private ObjectName target;
/*     */     String method;
/*     */     Object[] args;
/*     */     String[] sig;
/*     */
/*     */     MBeanServerAction() {
/*     */     }
/*     */
/*     */     MBeanServerAction(ObjectName target, String method, Object[] args, String[] sig) {
/* 877 */       this.target = target;
/* 878 */       this.method = method;
/* 879 */       this.args = args;
/* 880 */       this.sig = sig;
/*     */     }
/*     */
/*     */     public Object run() throws Exception
/*     */     {
/* 885 */       Object rtnValue = PooledInvoker.this.server.invoke(this.target, this.method, this.args, this.sig);
/* 886 */       return rtnValue;
/*     */     }
/*     */
/*     */     Object invoke(ObjectName target, String method, Object[] args, String[] sig) throws Exception
/*     */     {
/* 891 */       SecurityManager sm = System.getSecurityManager();
/* 892 */       Object rtnValue = null;
/* 893 */       if (sm == null)
/*     */       {
/* 896 */         rtnValue = PooledInvoker.this.server.invoke(target, method, args, sig);
/*     */       }
/*     */       else
/*     */       {
/*     */         try
/*     */         {
/* 903 */           MBeanServerAction action = new MBeanServerAction(PooledInvoker.this, target, method, args, sig);
/* 904 */           rtnValue = AccessController.doPrivileged(action);
/*     */         }
/*     */         catch (PrivilegedActionException e)
/*     */         {
/* 908 */           Exception ex = e.getException();
/* 909 */           throw ex;
/*     */         }
/*     */       }
/* 912 */       return rtnValue;
/*     */     }
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.invocation.pooled.server.PooledInvoker
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.invocation.pooled.server.PooledInvoker$MBeanServerAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.