All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rzo.yajsw.app.WrapperMainServiceWin Maven / Gradle / Ivy

Go to download

YAJSW is a java centric implementation of the java service wrapper by tanuki (JSW). It aims at being mostly configuration compliant with the original. It should therefore be easy to switch from JSW to YAJSW.

The newest version!
/* This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 

* This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.rzo.yajsw.app; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import jnacontrib.win32.Win32Service; import org.rzo.yajsw.Constants; import org.rzo.yajsw.boot.WrapperLoader; import org.rzo.yajsw.config.YajswConfigurationImpl; import org.rzo.yajsw.os.OperatingSystem; import org.rzo.yajsw.os.Process; import org.rzo.yajsw.os.StopableService; import org.rzo.yajsw.os.ms.win.w32.WindowsXPProcess; import org.rzo.yajsw.wrapper.WrappedProcess; import org.rzo.yajsw.wrapper.WrappedProcessFactory; import org.rzo.yajsw.wrapper.WrappedProcessList; // TODO: Auto-generated Javadoc /** * The Class WrapperMainService. */ public class WrapperMainServiceWin extends Win32Service implements StopableService { /** The w. */ static volatile WrappedProcessList wList = new WrappedProcessList(); static volatile WrappedProcess w; static volatile boolean _waitOnStop = false; /** The service. */ static WrapperMainServiceWin service; static ExecutorService pool = Executors.newFixedThreadPool(5); /** * Instantiates a new wrapper main service. */ public WrapperMainServiceWin() { } private static int getPriority(YajswConfigurationImpl config) { String priority = config.getString("wrapper.ntservice.process_priority", ""); if ("LOW".equals(priority)) return Process.PRIORITY_LOW; else if ("BELOW_NORMAL".equals(priority)) return Process.PRIORITY_BELOW_NORMAL; else if ("NORMAL".equals(priority)) return Process.PRIORITY_NORMAL; else if ("ABOVE_NORMAL".equals(priority)) return Process.PRIORITY_ABOVE_NORMAL; else if ("HIGH".equals(priority)) return Process.PRIORITY_HIGH; return Process.PRIORITY_UNDEFINED; } // this is the wrapper for services /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { String wrapperJar = WrapperLoader.getWrapperJar(); // set home dir of the service to the wrapper jar parent, so that we may find required libs String homeDir = new File(wrapperJar).getParent(); if (!OperatingSystem.instance().setWorkingDir(homeDir)) System.out.println("could not set working dir. pls check configuration or user rights :"+homeDir); YajswConfigurationImpl _config = new YajswConfigurationImpl(false); boolean debug = _config.getBoolean("wrapper.debug", false); service = new WrapperMainServiceWin(); // set service shutdown timeout service.setServiceName(_config.getString("wrapper.ntservice.name")); long timeout = _config.getInt("wrapper.shutdown.timeout", Constants.DEFAULT_SHUTDOWN_TIMEOUT) * 1000; timeout += _config.getInt("wrapper.script.STOP.timeout", 0) * 1000; timeout += _config.getInt("wrapper.script.SHUTDOWN.timeout", 0) * 1000; timeout += _config.getInt("wrapper.script.IDLE.timeout", 0) * 1000; timeout += _config.getInt("wrapper.script.ABORT.timeout", 0) * 1000; if (timeout > Integer.MAX_VALUE) timeout = Integer.MAX_VALUE; service.setStopTimeout((int) timeout); timeout = _config.getInt("wrapper.startup.timeout", Constants.DEFAULT_STARTUP_TIMEOUT) * 1000; if (timeout > Integer.MAX_VALUE) timeout = Integer.MAX_VALUE; service.setStartupTimeout((int) timeout); service.setAutoReportStartup(_config.getBoolean("wrapper.ntservice.autoreport.startup", true)); if (_config.containsKey("wrapperx.config")) { List configs = _config.getList("wrapperx.config"); wList = WrappedProcessFactory.createProcessList(new HashMap(), configs, true); for (WrappedProcess p : wList) { p.setService(service); } } else { WrappedProcess w = WrappedProcessFactory.createProcess(_config); // set service in wrapper so that we may stop the service in case the application terminates and we need to shutdown the wrapper w.setService(service); w.init(); wList.add(w); } w = wList.get(0); int priority = getPriority(_config); if (priority != -1) { int myPid = OperatingSystem.instance().processManagerInstance().currentProcessId(); WindowsXPProcess.setProcessPriority(myPid, priority); } // start the applications // the wrapper may have to wait longer for the application to come up -> // start the application // in a separate thread and then check that the wrapper is up after a // max timeout // but return as soon as possible to the windows service controller final long maxStartTime = w.getMaxStartTime(); final Future future = pool.submit(new Runnable() { public void run() { try { Thread.yield(); wList.startAll(); } catch (Throwable ex) { ex.printStackTrace(); w.getWrapperLogger().info("Win Service: error starting wrapper " + ex.getMessage()); Runtime.getRuntime().halt(999); } } }); pool.execute(new Runnable() { public void run() { try { future.get(maxStartTime, TimeUnit.MILLISECONDS); } catch (Exception ex) { ex.printStackTrace(); w.getWrapperLogger().info("Win Service: wrapper did not start within " + maxStartTime + " ms " + ex.getMessage()); Runtime.getRuntime().halt(999); } } }); if (debug) w.getWrapperLogger().info("Win service: before service init"); service.setDebug(debug); // init the service for signaling with services.exe. app will hang // here until service is stopped service.init(); // service has terminated -> halt the wrapper jvm if (debug) w.getWrapperLogger().info("Win service: terminated correctly"); try { if (_config.getBoolean("wrapper.update.auto", false)) { w.update(null, false); } } catch (Exception ex) { } Runtime.getRuntime().halt(0); } /* * (non-Javadoc) * * @see jnacontrib.win32.Win32Service#onStart() */ @Override public void onStart() { log("onstart"); } /* * (non-Javadoc) * * @see jnacontrib.win32.Win32Service#onStop() */ @Override public void onStop() { // execute in a separate thread so that the controller callback can return pool.execute(new Runnable() { public void run() { try { w.getWrapperLogger().info("Win service stop - timeout: "+service.getStopTimeout()); if (w.isHaltAppOnWrapper()) { w.getWrapperLogger().info("Win service wrapper.control -> stopping application"); // remove the listener, so it does not call System.exit wList.removeStateChangeListener(WrappedProcess.STATE_IDLE); wList.stopAll(_stopReason); } wList.shutdown(); w.getWrapperLogger().info("Win service stop - after shutdown"); synchronized (waitObject) { w.getWrapperLogger().info("Win service stop - before notify"); waitObject.notifyAll(); } w.getWrapperLogger().info("Win service terminated"); } catch (Exception e) { e.printStackTrace(); w.getWrapperLogger().throwing(this.getClass().getName(), "error in win service doStop", e); } } }); } public void log(String txt) { if (_debug && w != null && w.getWrapperLogger() != null) w.getWrapperLogger().info(txt); } public void waitOnStop() { int i = 0; try { while (!_waitOnStop && i++ < 20) Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }