4 votes

Comment restreindre l'exécution d'un JAR exécutable qui est exécuté indépendamment et peut être exécuté via une application web ?

J'ai un fichier JAR exécutable qui est programmé pour s'exécuter indépendamment à l'aide de la fonction Minuterie .

Le même JAR est exécuté par l'intermédiaire d'une application web (développée avec Spring MVC).

Je dois restreindre l'exécution de JAR dans une situation où si le jar est exécuté par le biais d'un timer, il n'est pas autorisé à s'exécuter par l'intermédiaire de l'application Web à ce moment-là.

Note : [ J'ai utilisé processbuilder pour exécuter le JAR. ]

1voto

Ali.Mojtehedy Points 380

Je pense que vous êtes en train de développer un jar licenciable. A mon humble avis, pour ce type de jar, il est préférable d'intégrer une base de données et d'enregistrer le temps d'exécution et l'utilisation du port dans la base de données, de comparer le temps d'utilisation et de le restreindre. L'approche par minuterie n'est pas sûre en raison de la différence de temps système ou de la résistance des antivirus ou de la résistance de l'allocation de temps système, etc. Cependant, pour surveiller le web, vous pouvez utiliser l'application WatchDog pour gérer ce type de problème,

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

}

1voto

Testo Testini Points 161

Si je comprends bien, vous avez différentes machines virtuelles qui exécutent le même jar/code (que j'appellerai fonctionnement ). Si c'est le cas, vous pouvez mettre en place un mécanisme de verrouillage indépendant de ces VM. Par exemple, vous pourriez utiliser un fichier, mais il est préférable d'utiliser la base de données et ses fonctions de verrouillage natives : créez un tableau "Verrous" (ID, version, opération, expiration) puis, à chaque fois que l'opération s'exécute, essayez de récupérer une ligne de verrouillage pour l'opération, si la ligne n'existe pas ou est expirée, créez/mettez à jour une ligne de verrouillage définissant l'expiration et autorisez l'opération, sinon levez l'exception "cannot-execute-since-locked" (ne peut être exécuté depuis le verrouillage). L'expiration est utilisée pour éviter un verrouillage définitif si l'opération se bloque, comme dans le cas suivant finally n'a pas pu être exécutée (par exemple : plantage du système d'exploitation). Pour éviter les écritures doubles/concurrentes, vous devez utiliser DB verrouillage optimiste pour la table Lock, par exemple : un champ Version. Libérez le verrou à la fin de l'opération en supprimant la ligne. Les lignes de verrouillage doivent être créées et supprimées dans des transactions distinctes, séparées de celles de l'opération (le cas échéant).

1voto

Sourabh Points 344

Ce dont vous avez essentiellement besoin, c'est d'un verrou qui fonctionne dans tous les jvms. Ou, disons, un moyen de partager des objets entre les jvms afin de pouvoir prendre un verrou sur eux. Il existe de nombreuses solutions, comme la création d'un fichier pour indiquer un verrou, ou un verrou basé sur une base de données si vous avez déjà une base de données dans votre application, ou un verrou de distribution. Terre cuite est l'une des solutions possibles. Vous pouvez essayer apache zookeeper également, et conservateur toujours issue d'Apache, la rend très facile à utiliser.

Zookeeper et curator : le code semble aussi simple que :

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

Exemple complet : aquí

1voto

gladiator Points 764

La meilleure façon de procéder est d'utiliser la base de données. Au début de l'application, verrouiller une ligne particulière (en utilisant la fonction pour la mise à jour par sécurité au cas où les deux démarrent en même temps) et écrire en_utilisation dans une certaine colonne . Ensuite, faites votre affaire, une fois que c'est fait, mettez à jour la même ligne à partir de en_utilisation à achevé . De cette façon, à un moment donné, une instance de votre jar exécutera votre code d'entreprise, et il n'y aura pas d'échec si les deux se trouvent sur des machines différentes.

1voto

firephil Points 163

Vous pourriez vérifier si un fichier existe afin de signaler que le .jar est en cours d'exécution et si oui, terminer :

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

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X