tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andy Gumbrecht <andy.gumbre...@orprovision.com>
Subject Re: Running standalone server as a windows service
Date Mon, 23 Nov 2009 07:42:52 GMT
Hi Selvan,

The Java Service Wrapper is no longer free, so I went on the hunt - Its 
a shame really, because it was developed largely by the community.

It is not rocket science to actually dig into the Java.c from Sun and 
get a basic service running yourself - It is a little more hard to cater 
for everyone though, and that is where the JSW finds it's commercial 
strength.

Anyway, I used this project 'http://jslwin.sourceforge.net/' (Thanks 
Michael) to get OpenEJB running as a service using:

1. A simple controller...

public class ServiceController {

     private final static Log log = 
LogFactory.getLog(ServiceController.class);

     private static Server _server;

     public ServiceController() {
     }

     public static void main(String[] args) {

         final File dir;

         try {
             dir = new File(System.getProperty("standalone.server.dir"));

             if (!dir.exists()) {
                 log.fatal(String.format("System property 
'standalone.server.dir' is invalid: %s", dir));
                 throw new RuntimeException("System property 
'standalone.server.dir' is invalid");
             }
         } catch (Exception e) {
             log.fatal("System property 'standalone.server.dir' not found");
             throw new RuntimeException("System property 
'standalone.server.dir' not found!");
         }

         log.info(String.format("Configuring server at: %s", dir));

         _server = new ServerOpenEJB(dir.getAbsolutePath());

         Thread t = new Thread() {
             public void run() {
                 ServiceController.start();

                 while (true) { //System.exit
                     try {
                         Thread.sleep(Integer.MAX_VALUE);
                     } catch (InterruptedException e) {
                         //Ignore
                         log.debug("Service was interrupted");
                     }
                 }
             }
         };

         t.start();

         try {
             t.join();
         } catch (InterruptedException e) {
             log.debug("InterruptedException:", e);
         }
     }

     public static void start() {
         log.info("Starting service");
         resume();
         log.info("Started service");
     }

     public static void stop() {

         log.info("Stopping service");
         pause();
         log.info("Stopped service");
         LogFactory.releaseAll();

         Thread.yield();

         System.exit(0);
     }

     public static void pause() {
         log.info("Pausing service");
         if (null != _server) {
             _server.stop();
         }
     }

     public static void resume() {
         if (null != _server) {
             if (!_server.isStarted()) {
                 log.info("Resuming service");
                 _server.restart();
             }
         }
     }
}

2. A server wrapper (Modified the existing OpenEJB invoker code, so 
thank you OpenEJB team)

public class ServerOpenEJB implements Server {

     private static final Log log = LogFactory.getLog(ServerOpenEJB.class);
     private final String _path;

     public ServerOpenEJB(String path) {

         if (!path.endsWith(File.separator)) {
             path += File.separator;
         }

         _path = path;
     }

     @Override
     public boolean isStarted() {
         return connect();
     }

     @Override
     public boolean restart() {
         if (stop()) {
             return start();
         }

         return false;
     }

     public boolean start() {

         if (!connect()) {

             forkServerProcess("start");
             return connect(10, "localhost", 4201);

         } else {
             log.debug(":: Remote OpenEJB already started ::");
             return true;
         }
     }

     @Override
     public boolean stop() {

         if (connect()) {

             OutputStream out = null;
             Socket socket = null;

             try {
                 socket = new Socket("localhost", 4200);
                 out = socket.getOutputStream();
                 out.write("Stop".getBytes());
             } catch (Exception e) {
                 //Ignore
             } finally {
                 try {
                     out.close();
                 } catch (IOException e) {
                     //Ignore
                 }
                 try {
                     socket.close();
                 } catch (IOException e) {
                     //Ignore
                 }
             }

             return disconnect(10, "localhost", 4201);

         } else {
             log.debug(":: Remote OpenEJB is not running ::");
             return true;
         }
     }

     public static boolean connect() {
         return connect(1, "localhost", 4201);
     }

     private void forkServerProcess(final String option) {

         try {

             ArrayList<String> cmd = new ArrayList<String>();
             String s = java.io.File.separator;
             String java = System.getProperty("java.home") + s + "bin" + 
s + "java";

             cmd.add(java);
             addSystemProperties(cmd);
             cmd.add("-classpath");
             //cmd.add(getClasspath());
             cmd.add(_path + "lib");
             //cmd.add("org.apache.openejb.server.Main");
             cmd.add("-jar");

             //Find the core jar.
             final File[] libs = new File(_path + "lib").listFiles();
             File core = null;

             for(File f : libs){
                 if(f.getName().toLowerCase().indexOf("openejb-core") > -1){
                     core = f;
                 }
             }

             if(null == core){
                 throw new Exception("Did not find core library");
             }

             cmd.add(core.getAbsolutePath());
             cmd.add(option);

             String[] command = (String[]) cmd.toArray(new String[0]);

             Runtime runtime = Runtime.getRuntime();
             Process server = runtime.exec(command, null, new File(_path));

             Thread serverOut = new Thread(new 
Pipe(server.getInputStream(), System.out));
             serverOut.setDaemon(true);
             serverOut.start();

             Thread serverErr = new Thread(new 
Pipe(server.getErrorStream(), System.err));
             serverErr.setDaemon(true);
             serverErr.start();

         } catch (Exception e) {
             throw new RuntimeException("Cannot start the OpenEJB 
server.",e);
         }

     }

     private void addSystemProperties(ArrayList<String> cmd) {

         Set set = System.getProperties().entrySet();

         for (Iterator iter = set.iterator(); iter.hasNext();) {

             Map.Entry entry = (Map.Entry) iter.next();
             String key = (String) entry.getKey();
             String value = (String) entry.getValue();

             if (key.matches("^-X.*")) {
                 cmd.add(key + value);
             } else if 
(!key.matches("^(java|javax|os|sun|user|file|awt|line|path)\\..*")) {
                 cmd.add("-D" + key + "=" + value);
             }
         }

     }

     public static boolean connect(int tries, String host, int port) {

         Socket s = null;

         try {

             s = new Socket(host, port);
             s.getOutputStream().close();

         } catch (Exception e) {

             if (tries < 2) {
                 return false;
             } else {

                 try {
                     Thread.sleep(2000);
                 } catch (Exception e2) {
                     e.printStackTrace();
                 }

                 return connect(--tries, host, port);
             }
         } finally {
             try {
                 s.close();
             } catch (Exception e) {
             }
         }

         return true;
     }

     public static boolean disconnect(int tries, String host, int port) {

         Socket s = null;

         try {

             s = new Socket(host, port);
             s.getOutputStream().close();

             try {
                 s.close();
             } catch (Exception e) {
             }

             if (tries < 2) {
                 return false;
             } else {

                 try {
                     Thread.sleep(2000);
                 } catch (Exception e2) {
                 }

                 return disconnect(--tries, host, port);
             }

         } catch (Exception e) {

         } finally {
             try {
                 s.close();
             } catch (Exception e) {
             }
         }

         return true;
     }

     private static final class Pipe implements Runnable {

         private final InputStream is;
         private final OutputStream out;

         private Pipe(InputStream is, OutputStream out) {
             super();
             this.is = is;
             this.out = out;
         }

         public void run() {

             try {

                 int i = is.read();
                 out.write(i);

                 while (i != -1) {
                     i = is.read();
                     out.write(i);
                 }

             } catch (Exception e) {
                 e.printStackTrace();
             }

         }

     }
}

The JSL service configuration is well documented and I am sure the above 
code can be tweaked to your needs.

Best regards,

Andy.

On 23.11.2009 03:04, rtselvan wrote:
> It could be that I missed the documentation on it.
>
> Is there a wrapper integration to run openEJB as standalone windows service?
> openejb.bat doesn't have any option to install the open ejb as windows
> service (like tomcat).
>
> Thanks
> /selvan
>    

Mime
View raw message