Как ограничить выполнение исполняемого файла JAR, который выполняется независимо и может выполняться через веб-приложение?

У меня есть один исполняемый JAR-файл, который планируется запускать независимо с помощью Timer .

Тот же JAR выполняется через веб-приложение (разработанное весной MVC).

Я должен ограничить выполнение JAR в ситуации, когда если jar выполняется через таймер, то в это время ему не разрешено выполняться через веб-приложение.

Примечание. [Я использовал ProcessBuilder для выполнения JAR.]


person Amit Kumar    schedule 19.11.2016    source источник
comment
Под таймером вы имеете в виду задание cron для конкретной ОС?   -  person mika    schedule 19.11.2016
comment
@mika yes.it планируется выполнять через определенные промежутки времени.   -  person Amit Kumar    schedule 19.11.2016
comment
Лучшим решением, вероятно, было бы заставить ваше приложение использовать инструмент ОС, который может возвращать список всех запущенных процессов. Если вы найдете имя приложения в списке, оно уже запущено. Вы также можете работать с подходом семафора, в котором вы пишете, например. PID вашего приложения в файл и (опять же) используйте инструмент ОС для поиска, используется ли PID в настоящее время... но это, вероятно, более подвержено ошибкам и на самом деле еще больше кода. К вашему сведению, посмотрите здесь: stackoverflow.com/questions/2318220/   -  person mika    schedule 19.11.2016
comment
@mika, но это решение ограничено рамками jar и веб-приложения, работающими на одном компьютере. если вы по-прежнему хотите сделать это в кластерной среде, вам нужно записать файл в NFS< /а> местоположение.   -  person Sourabh    schedule 29.11.2016


Ответы (5)


Я думаю, вы разрабатываете лицензионный jar . По моему скромному мнению, для такого рода банок лучше всего встроить базу данных и сэкономить время выполнения и использование порта в Db, а также сравнить время использования и ограничить его. Подход с таймером небезопасен из-за разницы системного времени, разрешения антивируса или разрешения распределения системного времени и т. д. Однако для веб-мониторинга вы можете использовать приложение WatchDog для решения такого рода проблем,

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();
    }
    }

}
person Ali.Mojtehedy    schedule 24.11.2016

Если я правильно понимаю, у вас есть разные виртуальные машины, которые выполняют один и тот же jar/код (который я буду называть операцией). Если это так, вы можете настроить механизм блокировки, независимый от этих виртуальных машин. Например, вы можете использовать файл, но лучше использовать БД и ее собственные функции блокировки: создайте таблицу «Блокировки» (идентификатор, версия, операция, срок действия), а затем каждый раз, когда операция выполняется, пытайтесь получить строку блокировки для операции, если строка не существует или срок ее действия истек, затем создайте/обновите срок действия параметра блокировки строки и разрешите операцию, в противном случае создайте исключение «невозможно выполнить с момента блокировки». Истечение срока действия используется для того, чтобы навсегда избежать блокировки в случае сбоя операции, поскольку finally не может быть выполнено (например, сбой ОС). Чтобы избежать двойной/одновременной записи, вы должны использовать функцию БД оптимистическая блокировка для таблицы блокировки. , например: поле Версия. Снимите блокировку в конце операции удаления строки. Строки блокировки должны создаваться и удаляться в отдельных транзакциях, отдельно от операций (если таковые имеются).

person Testo Testini    schedule 26.11.2016

Лучший способ сделать это - использовать базу данных. При запуске приложения заблокируйте определенную строку (используя для обновления для безопасности на случай, если оба запустятся одновременно) и напишите там in_use в каком-либо столбце. Тогда займитесь делом, когда закончите, обновите ту же строку с in_use на completed. Таким образом, в определенное время на одном экземпляре вашего jar-файла будет выполняться ваш бизнес-код. Также он не сработает, если оба находятся на разных машинах.

person gladiator    schedule 28.11.2016

Вы можете проверить, существуют ли файлы, чтобы сигнализировать о том, что .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();
}

}

person firephil    schedule 28.11.2016

По сути, вам нужна блокировка, которая работает через jvms. Или, скажем, способ совместного использования объекта между jvms, чтобы вы могли заблокировать их. Здесь доступно несколько решений, таких как создание файла для указания блокировки или блокировка на основе базы данных, если у вас уже есть база данных в вашем приложении, или блокировка распределения. Одним из возможных решений здесь является Terracotta. Вы также можете попробовать apache zookeeper и curator, опять же от apache, делает ее очень простой в использовании.

Zookeeper и куратор: код выглядит так же просто, как:

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

Полный пример: здесь

person Sourabh    schedule 27.11.2016