IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

Exécuter un batch Spring par une commande shell


Sujet :

Spring Java

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Par défaut Exécuter un batch Spring par une commande shell
    Hello tous,

    Voici mon cas :
    Sur un serveur, j'ai une webapp entièrement "springifiée".
    Il y a des spring batch dedans.

    Un admin système veut pouvoir lancer ces batch spring via un shell script : bsh myscript.sh
    Alors la webapp tourne avec son IHM qui va bien, et d'un autre côté, elle est sollicité par les admin qui lancent des batch en ligne de commande.
    L'idée est d'avoir les spring batch dans l'appli de défini.
    Comme ça au démarrage de la webapp j'ai un seul spring bean container (app-context.xml) de chargé.
    Je veux que le script lance un spring batch qui est défini dans la webapp mais sans lancer une nouvelle JVM ou charger un nouveau app-context.xml.
    En gros, je veux un seul context transactionnelle, que la base soit attaquée par l'IHM ou par un script qui lance un batch.

    Comment être sûr que tout se lance dans la JVM et l'application-contexte chargé via la webapp ?

  2. #2
    Membre chevronné Avatar de freddou17
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 341
    Par défaut
    salut,
    il te faut un bean spring dans lequel tu injectes le spring context de ta webapp et qui est décrit par une classe contenant un main.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class MaClasseDeLancementBatchStandalone {
     
        @Autowired 
         private ApplicationContext appCtx; // en espérant qu'il soit injecté 
     
        static int Main(string[] args){
            // le tableau args est rempli/initialisé par ton .sh
            // ton .sh appelle cette classe en lançant un java -cp ....
            //appCtx.getBean("tonBatch") selon tes paramètres
        }
     
    }
    par contre pour la jvm tu peux utiliser la même que ton serveur mais tu vas déclencher un nouveau process...

    Voilà, une idée de réflexion.
    PS: ton raisonnement implique que ton serveur soit démarrer si jamais les batchs doivent s’exécuter même serveur éteint tu devras forcement lire ton context spring à chaque batch

    ++

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Par défaut
    ok merci pour cette réflexion.
    En faisant un java -cp .... c'est un nouveau process java qui se lance, c'est mal parti pour hériter un contexte applicatif !

    J'ai trouvé une doc qui dit comment lancer un batch avec Spring Batch en mode standalone :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mvn exec:java -Dexec.mainClass=org.springframework.batch.core.launch.support.CommandLineJobRunner -Dexec.args="simpleJob.xml simpleJob"
    Source : https://dzone.com/articles/spring-batch-hello-world-1

    Par contre, ils ont l'air de charger un nouveau applicationContext. Moi il est déjà chargé avec la webapp.

  4. #4
    Membre chevronné Avatar de freddou17
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 341
    Par défaut
    re,

    Pour moi tu seras obligé de recharger le context et/ou de lancer un nouveau process.
    Pour moi les batchs sont des traitements totalement détachés du serveur d'appli. Càd qu'ils peuvent s’exécuter que celui-ci soit éteint ou non.
    Le code que tu as ajouté correspond à une commande maven qui lance un java -cp, rien d'autre...

    Sinon avec mon raisonnement (que je n'ai pas testé), tu devrais peut-être pouvoir récupérer le contexte spring mais ne t'épargneras pas un nouveau process.

    De plus pourquoi tu ne veux pas recharger un app-context.xml (le contexte sera détruit à la fin du batch). Est-ce vraiment le même au niveau des scopes, des commit et rollback, as-tu besoin de scanner les mêmes packages, as tu besoin de ta couche VIEW/Request mapping?
    Si ton admin a besoin du contexte de ton server, pourquoi faire un .sh, il n'a qu'à se connecter à ton appli et utiliser l'IHM?

    Bon courage
    ++

  5. #5
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Par défaut
    ok merci pour ces infos.

    En effet, la commande maven lancera un nouveau process.
    Qui dit nouveau processus java dit forcément contexte spring séparé (chargé par la webapp et le spring batch) j'imagine, me trompe-je ?
    En fait je cherche à ne charger qu'un seul contexte à cause du transaction manager.
    Je sais pas, si un user clique sur "ajouter" sur la webapp via l'ihm, ça génère l'id d'insertion x+1.
    La même opération, effectué "simultanément" côté batch va générer le même id.
    Après j'imagine que c'est un cas extrême, mais je raisonne d'un point de vue technique....
    Forcément en base, ça va poser problème (et tous les accès concurrents en écriture en général).

    Après c'est sûr que se connecter à l'ihm et cliquer est plus simple pour tout le monde.
    Mais c'est mes specs (pour l'instant).
    Je pense que l'analyste imagine un "simple" script shell qui lance un programme java "main" dans un thread séparé du coup pour faire des trucs en base.
    Chose que j'associe à un batch spring plus simplement (il me faudra dans tous les cas injecter les contextes spring).

    L'analyste à exprimé son besoin, à moi d'exposer les contraintes ou propositions techniques adéquats (je suis open sur la question, et je m'intéresse à spring batch pour répondre à ce besoin).

    NB : la webapp sera du spring-data-jpa/spring mvc rest.

  6. #6
    Membre chevronné Avatar de freddou17
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 341
    Par défaut
    ok,
    Du coup pourquoi l'id n'est pas auto-increment?
    Les batchs sont-ils lancés n'importe quand ou juste lorsque le serveur tombe (apparemment non) ?
    Tes batchs ne peuvent-ils pas générer des fichiers avec des ordres sql et, un autre batch lui-même exécuté à 3h du matin par exemple, 'jouerait" ces fichiers. (en partie du principe qu'il n'y a pas d'activité à 3h du matin)
    Ce sont des pistes...

    ++

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 962
    Par défaut
    Citation Envoyé par freddou17 Voir le message
    re,
    Sinon avec mon raisonnement (que je n'ai pas testé), tu devrais peut-être pouvoir récupérer le contexte spring mais ne t'épargneras pas un nouveau process.
    Attention: vous ne pourrez pas utiliser un contexte d'application Web dans un tool, il faudra bien séparer les contextes des différentes couches de votre application en modules indépendants
    (que ce soit des .xml ou des @Configuration) et vous pourrez ré-utiliser ceux des couches non-Web dans le tool.

    Vous pourrez alors construire un ConfigurableApplicationContext
    si vos contextes sont en .xml via ClassPathXmlApplicationContext
    si vos contextes sont des @Configuration via GenericApplicationContext + AnnotatedBeanDefinitionReader.register + AnnotationConfigUtils.registerAnnotationConfigProcessors

    dans les 2 cas il faut terminer le processus de construction par
    context.getBeanFactory().autowireBeanProperties( ... )
    pour que les dépendances soient injectées dans vos beans.

    NB
    si vous devez spécifier un ou des profil(s) Spring, vous pouvez le faire en invoquant System.setProperty("spring.profiles.active", ...)
    AVANT d'appeler new ClassPathXmlApplicationContext|GenericApplicationContext().

  8. #8
    Membre éprouvé

    Homme Profil pro
    Developpeur
    Inscrit en
    Mars 2011
    Messages
    115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Mars 2011
    Messages : 115
    Par défaut
    Bonjour,
    Une idée. Créer un service rest qui lance ton job spring batch. Pour l’état, il faudra scruter la table spring batch ou créer des flags car spring batch est asynchrone.
    Tu appelles ensuite ton service dans ton script en utilisant curl ou wget par exemple.

  9. #9
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Par défaut
    Merci pour vos retours !

    Bon j'en ai reparlé avec mon architecte de la boîte à propos de ces batchs.
    A priori il veut du simple : Spring Batch trop lourd !
    Il a probablement raison, l'idée de mon côté était "d'uniformiser" la structure des batchs (J'en ai 5 à coder, et c'est un concept central à l'application). Après les valeurs apportées de Spring Batch :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Features
     
        Transaction management
        Chunk based processing
        Declarative I/O
        Start/Stop/Restart
        Retry/Skip
        Web based administration interface (Spring Batch Admin)
    Je doute que j'en ai besoin...

    Du coup, je retiens l'idée d'un appel REST comme point d'entrée : plus besoin de .bat ou .sh, on passe par le navigateur et Spring Security (déjà présent) gère le login / mdp et le role si apte à lancer la méthode REST.
    Cela est complètement transparent pour moi et l'utilisateur. Pas de page Web à coder (la page de connexion existe déjà). Après si la personne veut un beau compte rendu de l'execution du batch une fois terminé, il achètera une page Web....cela n'est pas prévu.
    Par contre, l'appli doit tourner H24 .... contrairement à un script .sh qui lance un programme Java.
    Mais je pense que c'est un bon choix.

    Je vais confirmer la solution ....

    Merci !

Discussions similaires

  1. Exécuter une commande shell depuis Eclipse
    Par omsi02 dans le forum Eclipse Platform
    Réponses: 3
    Dernier message: 05/02/2010, 10h52
  2. Exécuter une commande shell dans une requête
    Par GLDavid dans le forum Requêtes
    Réponses: 2
    Dernier message: 25/11/2009, 16h06
  3. Exécution d'une commande shell
    Par darklord159 dans le forum Ada
    Réponses: 1
    Dernier message: 31/05/2008, 14h24
  4. [VBA]Exécuter une commande Shell
    Par antoine46 dans le forum VBA Access
    Réponses: 4
    Dernier message: 16/04/2008, 08h07
  5. Réponses: 9
    Dernier message: 30/05/2006, 19h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo