2016-11-19 99 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(); 
} 

}