2016-11-19 98 views
4

我有一个计划使用定时器独立运行的可运行JAR文件。如何限制独立执行并可通过Web应用程序执行的可运行JAR的执行。

相同的JAR通过web应用程序(在spring MVC中开发)执行。

如果jar通过计时器执行,那么当时不允许通过web应用程序执行,我必须限制JAR的执行。

注意:[我已经使用processbuilder来执行JAR。]

+0

随着计时器你说的是操作系统特定的cron作业? – mika

+0

@mika yes.it计划按时间间隔执行。 – bajrangi

+1

最好的解决方案可能是让您的应用程序使用一个操作系统工具,该工具可以返回所有正在运行的进程的列表。如果您在列表中找到应用程序的名称,它已经在运行。您也可以使用信号量方法,例如在其中写入把你的应用程序的PID写入一个文件,然后(再次)使用操作系统工具来查找PID当前是否正在使用......但这可能更容易出错,实际上甚至有更多的编码需要执行。 Fyi,看看这里:http://stackoverflow.com/questions/2318220/how-to-detect-via-java-whether-a-particular-process-is-running-under-windows – mika

回答

1

我想你正在开发可授权的jar。 在我看来,对于这种瓶子,最好是嵌入数据库,并保存Db中的执行时间和端口使用情况,并比较使用时间并对其进行限制。计时器的做法是不安全的,由于系统时间差异或防病毒资源或系统时间分配RE等。然而,对于监控器网络,你可以监视应用程序来处理这类问题,

public class Watchdog implements Runnable { 

private Vector observers = new Vector(1); 
private long timeout = -1; 
private volatile boolean stopped = false; 
public static final String ERROR_INVALID_TIMEOUT = "timeout less than 1."; 

/** 
* Constructor for Watchdog. 
* @param timeout the timeout to use in milliseconds (must be >= 1). 
*/ 
public Watchdog(long timeout) { 
    if (timeout < 1) { 
     throw new IllegalArgumentException(ERROR_INVALID_TIMEOUT); 
    } 
    this.timeout = timeout; 
} 

public void addTimeoutObserver(TimeoutObserver to) { 
    observers.addElement(to); 
} 

public void removeTimeoutObserver(TimeoutObserver to) { 
    //no need to synchronize, as Vector is always synchronized 
    observers.removeElement(to); 
} 

protected final void fireTimeoutOccured() { 
    Enumeration e = observers.elements(); 
    while (e.hasMoreElements()) { 
     ((TimeoutObserver) e.nextElement()).timeoutOccured(this); 
    } 
} 

/** 
* Start the watch dog. 
*/ 
public synchronized void start() { 
    stopped = false; 
    Thread t = new Thread(this, "WATCHDOG"); 
    t.setDaemon(true); 
    t.start(); 
} 

/** 
* Stop the watch dog. 
*/ 
public synchronized void stop() { 
    stopped = true; 
    notifyAll(); 
} 


public synchronized void run() { 
    final long until = System.currentTimeMillis() + timeout; 
    long now; 
    while (!stopped && until > (now = System.currentTimeMillis())) { 
     try { 
      wait(until - now); 
      Boolean SafeToContinue=CheckDbCountDay(); 
      if(SafeToContinue) 
      ExecJarUsingStrategyPattern(new StrategyDoIt()); 
      else ExecJarUsingStrategyPattern(new showMessage()); 

     } catch (InterruptedException e) { 
      callBack("plz call support"); 
     } 
    } 
    if (!stopped) { 
     fireTimeoutOccured(); 
    } 
    } 

} 
1

如果我理解正确你有不同的虚拟机执行相同的jar /代码(我将调用操作)。如果是这样,你可以设置一个锁定机制,独立于这些虚拟机。例如,您可以使用文件,但更好地使用数据库及其原生锁定功能:创建一个“锁定”(ID,版本,操作,到期)表,然后每次执行操作时尝试检索操作的锁定行,if行不存在或过期,则创建/更新锁定行设置过期并允许操作,否则抛出无法执行自锁定异常。如果操作崩溃,过期用于永远避免锁定,因为finally无法执行(例如:OS崩溃)。为了避免双重/同时写入,您应该为锁定表使用DB optimistic locking功能,例如:版本字段。在操作结束时释放锁,删除该行。锁定行必须在不同的交易中创建和删除,与操作(如果有的话)分开创建和删除

1

实质上,您需要的是一个可以跨jvms工作的锁。或者,可以说,一种在jvms之间共享对象的方式,以便您可以锁定它们。这里有多种可用的解决方案,例如创建一个文件来指示一个锁,或者如果您的应用程序中已经有数据库,或者分发锁,则可以使用基于数据库的锁。 Terracotta是一个可能的解决方案。您也可以尝试apache zookeeper,而且来自apache的curator库使它非常易于使用。

动物园管理员和馆长:代码看起来简单:

lock = new InterProcessSemaphoreMutex(client, lockPath); 
lock.acquire(5, TimeUnit.MINUTES); 
// do something 
lock.release(); 

完整的例子:这样做是使用数据库here

1

的最佳方式。 开始应用程序锁定一个特定的行(使用更新为了安全起见,以便两者都在同一时间启动)并在某处写入in_use。 然后你做生意,一旦完成更新同一行从in_use完成。通过这种方式,在某个特定时间,您的jar的一个实例将执行您的业务代码。如果两者都在不同的计算机上,它也不会失败。

1

你可以检查是否存在的文件,以信号通知的.jar正在执行,如果是终止:

import java.io.File; 
import java.io.IOException; 

public class Main { 

public static void main(String[] args) { 


    if (FileLock.exists()){ 
     System.out.println("The file exists so the jar is running"); 
     System.exit(0); 
    } 


    FileLock.createLockFile(); 

    //start Running the .Jar File 
    /* 
    * 
    * 
    * CODE 
    * 
    * 
    * 
    */ 


    //Delete the file when the program terminates 
    FileLock.deleteLockFile(); 
    System.out.println("Program exiting normally"); 
} 

}

class FileLock { 

private static File lock = new File("jar-running.txt"); 

public static boolean exists() 
{ 
    return lock.exists(); 
} 

public static void createLockFile() 
{ 
    try { 

    lock.createNewFile(); 

} catch (IOException e) { 

    // the file already exists 
    System.exit(0);} 
} 

public static void deleteLockFile() 
{ 
    if(lock.exists()) lock.delete(); 
} 

}