J'ai créé un nouvel outil de déploiement Java

Problème de déploiement Java

Soudain, que faites-vous avec le déploiement Java?

Bien sûr, il existe de nombreuses façons de se déployer à la fin. Il y a, mais dans le langage de script, un projet léger qui peut être cloné git avec gem, pip, npm, etc. pour résoudre certaines dépendances, mais en ce qui concerne Java, la graisse du fat jar est étonnamment supprimée, ou le fichier jar Ce sera un style un peu subtil, tel que le générer et le remplacer manuellement. (Ce n'est pas le cas! Faites-moi savoir si vous avez une bonne solution)

En premier lieu, il semble que vous ne devriez pas écrire en Java avant un tel moment, mais on dit que Java (ou langage JVM) est légèrement requis, comme la réutilisation des actifs de code avec des outils périphériques ou la volonté d'effectuer un calcul parallèle avec un peu de multithreading. Existe encore.

Méthode de déploiement en Java

Tout d'abord, considérons la méthode de déploiement Java existante.

Transfert de code source

C'est une méthode pour essayer de faire quelque chose avec la même idée que le langage de script. Copiez le code source avec git ou un outil, résolvez les dépendances avec gradle (ci-après incluant maven / sbt / etc.) sur le serveur d'exécution, et construisez localement. Dans certains cas, il sera exécuté tel quel avec gradle.

avantage

Désavantage

Ce n'est pas une mauvaise méthode, mais cela ressemble plus à un serveur de développement qu'à une destination de déploiement car il contient l'ensemble complet. En outre, il est difficile d'affirmer qu'il n'a pas été modifié dans le serveur. Je crains que si j'apporte des modifications, que je construis et que quelqu'un essaie de faire quelque chose et de passer à une autre branche, je ne sais pas.

transfert de fichiers de classe

Il s'agit d'une méthode pour transférer un fichier .class qui est une compilation d'un fichier .java vers un serveur et l'exécuter.

avantage

Désavantage

Est-ce une méthode? J'avais l'habitude de le faire lorsque j'ai commencé à utiliser Java. C'est facile car il vous suffit de copier le fichier créé par l'EDI. Plutôt que de le déployer, c'est juste un moyen de l'exécuter sur un serveur. Si c'est un langage de script, c'est comme copier avec .zip ou .tar. C'est la pire méthode lorsqu'on considère le fonctionnement réel, comme ne pas avoir toutes les .classes, bien sûr ne pas bien connaître la version, ou les mélanger.

génération de fichier jar

Collectez les fichiers .class avec la commande IDE ou jar, ou transférez les fichiers .jar générés par gradle vers le serveur. Transférez également les fichiers .jar des bibliothèques dépendantes.

avantage

Désavantage

C'est une méthode légitime pour sa nature primitive. En termes de mise en œuvre, cela revient à envoyer un fichier .class au format zip, mais il est extrêmement facile à gérer car divers outils Java le prennent en charge.

Vous pouvez inclure du code source, des mémos, des documents, n'importe quoi, donc je pense que c'est toujours utile lorsque vous ne pouvez pas le gérer. Cependant, il est difficile de collecter tous les fichiers .jar qui ont des dépendances. Et différentes versions de .jar sont mélangées et cela devient Jar Hell au lieu de DLL Hell ...

Mettre ensemble dans un pot gras

La méthode royale. Reconstruisez toutes les bibliothèques dépendantes en un fichier jar exécutable. Puisque nous définissons main, nous pouvons faire ce qui suit:

> java -jar xxxx.jar arg1 arg2

Récemment (?) Semble être appelé uber jar ou shadow jar.

avantage

Désavantage

C'est une technique courante. La bonne chose est que vous ne pouvez transférer qu'un seul fichier. Tout est dedans, vous n'avez donc pas à vous soucier du fait qu'il soit partiellement mis à jour et terrible, et vous n'avez pas à vous soucier d'oublier la classe principale.

Personnellement, c'est trop gros (putain de gros), et quand je ne regarde que l'environnement de production, je ne connais pas tout de suite le nom de la bibliothèque utilisée ou la classe principale que j'utilise, donc je ne peux rien dire à moins de la décompresser. Cela ne convient pas vraiment à mon goût lors de l'exécution sur un serveur. Il vaut peut-être mieux fonctionner selon des règles de dénomination appropriées.

C'est un peu triste car je choisis parfois gros pot car il est difficile de collecter des fichiers de dépendance .jar tels que gradle. Cela ne semble pas être si courant, mais la bibliothèque de dépendances est [par ici](https://stackoverflow.com/questions/23109276/gradle-task-to-put-jars-from-maven-repository-into-project- Il est collecté par lib-folder).

Réunis dans un fichier de guerre

Vous pouvez faire de même avec de gros pots avec des fichiers war et ear, que vous voyez rarement en dehors du Web. war peut être plus approprié car il permet un contrôle plus fin tel que l'inclusion du fichier de paramètres d'application mais son exclusion du chemin de classe.

avantage

Désavantage

Je pense que le fichier war est utile si vous avez de nombreux environnements Java EE. S'il s'agit d'un fichier war, cela peut être acceptable même si la taille du fichier est un peu grande (biais)

Image Docker

Créez une image en créant un environnement d'exécution dans le conteneur Docker. L'image Java Docker est-elle lourde? Non, Alphine Linux / musc libc / Jigsaw le rend raisonnablement compact.

De nos jours, vous pouvez également créer une image Docker avec Maven / Gradle en une seule fois avec Google / Jib.

avantage

Désavantage

Ce sera désormais le favori. Le support Docker de Java progresse également, et on peut dire que les problèmes faciles à comprendre ont presque disparu. Il gère également les versions et vous n'avez pas à vous soucier d'être lié au comportement Java local.

Cependant, d'un autre côté, c'est Docker ... Il y a pas mal de situations qui ne conviennent pas à Docker, et c'est dommage de mettre une JVM capable de contrôler la mémoire de manière relativement simple dans un conteneur.

Pensez à une nouvelle méthode de déploiement

En examinant diverses choses, nous voulons résoudre les problèmes suivants pour un déploiement idéal.

Quel outil répond à cette exigence? En passant, si vous regardez d'autres langages, vous pouvez généralement déployer avec gem, pip, npm, etc. Le code principal peut être cloné git ou déployé à partir d'un référentiel privé. Les versions sont gérées dans le référentiel et vous pouvez voir ce qui s'est passé d'un seul coup en regardant l'environnement de production.

N'est-ce pas le cas avec Java? Compte tenu de cela, au moins le référentiel a un référentiel Maven. Je ne peux pas faire de git clone, qui nécessite une compilation, mais je pense que le support des référentiels privés est plus puissant que les autres langages. Après cela, ce serait bien s'il y avait un outil. .. ..

C'est pourquoi je l'ai fait.

marun https://github.com/nishemon/marun

Un outil pour télécharger les artefacts cibles à partir du référentiel Maven tout en résolvant les dépendances.

> marun install com.example:example:1.0.1

avantage

Désavantage

gradle et maven peuvent résoudre les dépendances, mais ils sont magnifiques car ils ne sont que des outils de construction, et ils ont la capacité de résoudre les dépendances dans les bibliothèques de dépendances (artefacts), mais ils ont la capacité de les gérer. Il n'y a aucune fonctionnalité permettant de télécharger uniquement les artefacts. Il existe un outil appelé Apach Ivy qui est spécialisé uniquement pour la résolution des dépendances dans le référentiel Maven, mais c'est aussi pour la construction en combinaison avec Apache Ant. Il est principalement considéré comme utilisé pour Ivy seul, et Ivy.xml doit être écrit pour l'utiliser seul.

J'ai donc utilisé Apache Ivy pour créer un outil qui télécharge uniquement les artefacts cibles et leurs dépendances.

J'ai besoin d'un référentiel privé, mais maintenant, par exemple, plugin maven-publish et [plugin aws-maven](https://qiita.com/ suzutt / items / bf1e8a8e425a9077b96c) facilite la création d'un référentiel Maven sur Amazon S3.

Installation

Il n'est pas bon d'être difficile à utiliser au début, il est donc installé avec pip. La partie ligne de commande est Python2 afin qu'elle fonctionne autant que possible avec le système Python.

> sudo pip install marun

init Initialisez pour le moment. Java est requis pour l'exécution, veuillez donc l'installer d'abord.

> sudo marun init
configuration file is not found!
Your Maven Repository URL []: s3://your_repository
S3 Access Key []:(Entrez la clé d'accès)
S3 Secret Key []:(Entrez la clé secrète)

En plus de s3, il peut également être utilisé avec http / https. Lorsque vous le saisissez, un fichier de paramètres * /etc/marun.conf * sera créé.

À propos, Ivy fera de son mieux pour télécharger les dépendances de marun lui-même comme ça. En raison d'Amazon S3, il existe de nombreuses dépendances de fichiers JAR. Trempez dans * / var / lib / marun *.

Ivy travaille dur


Download: 130982 / 130982
Download: 1282424 / 1282424
Download: 241622 / 241622
:: loading settings :: url = jar:file:/var/lib/marun/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: resolving dependencies :: caller#all-caller;working
	confs: [runtime]
	found jp.cccis.marun#marun;0.1.1 in maven.cccis.jp.s3.amazonaws.com
	found com.amazonaws#aws-java-sdk-s3;1.11.475 in bintray/jcenter
	[1.11.475] com.amazonaws#aws-java-sdk-s3;1.11.+
	found com.amazonaws#aws-java-sdk-kms;1.11.475 in bintray/jcenter
	found com.amazonaws#aws-java-sdk-core;1.11.475 in bintray/jcenter
	found commons-logging#commons-logging;1.1.3 in bintray/jcenter
	found org.apache.httpcomponents#httpclient;4.5.5 in bintray/jcenter
	found org.apache.httpcomponents#httpcore;4.4.9 in bintray/jcenter
	found commons-codec#commons-codec;1.10 in bintray/jcenter
	found software.amazon.ion#ion-java;1.0.2 in bintray/jcenter
	found com.fasterxml.jackson.core#jackson-databind;2.6.7.2 in bintray/jcenter
...
	commons-logging#commons-logging;1.1.3 from bintray/jcenter in [runtime]
	joda-time#joda-time;2.8.1 from bintray/jcenter in [runtime]
	jp.cccis.marun#marun;0.1.1 from maven.cccis.jp.s3.amazonaws.com in [runtime]
	org.apache.httpcomponents#httpclient;4.5.5 from bintray/jcenter in [runtime]
	org.apache.httpcomponents#httpcore;4.4.9 from bintray/jcenter in [runtime]
	software.amazon.ion#ion-java;1.0.2 from bintray/jcenter in [runtime]
	:: evicted modules:
	commons-logging#commons-logging;1.2 by [commons-logging#commons-logging;1.1.3] in [runtime]
	---------------------------------------------------------------------
	|                  |            modules            ||   artifacts   |
	|       conf       | number| search|dwnlded|evicted|| number|dwnlded|
	---------------------------------------------------------------------
	|      runtime     |   16  |   2   |   0   |   1   ||   17  |   1   |
	---------------------------------------------------------------------

Essayez d'utiliser

C'est une bonne idée de télécharger et d'exécuter quelque chose dans votre référentiel privé, mais ici, je vais essayer de télécharger le Google Closure Compiler.

> sudo marun install com.google.javascript:closure-compiler:+
:: loading settings :: url = jar:file:/var/lib/marun/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: resolving dependencies :: caller#all-caller;working
	confs: [runtime]
	found com.google.javascript#closure-compiler;v20181210 in repo1.maven.org
	[v20181210] com.google.javascript#closure-compiler;+
	found com.google.javascript#closure-compiler-externs;v20181028 in bintray/jcenter
	found args4j#args4j;2.0.26 in bintray/jcenter
	found com.google.errorprone#error_prone_annotations;2.3.1 in bintray/jcenter
	found com.google.guava#guava;25.1-jre in bintray/jcenter
	found org.checkerframework#checker-qual;2.0.0 in bintray/jcenter
	found com.google.j2objc#j2objc-annotations;1.1 in bintray/jcenter
	found org.codehaus.mojo#animal-sniffer-annotations;1.14 in bintray/jcenter
	found com.google.protobuf#protobuf-java;3.0.2 in bintray/jcenter
	found com.google.code.gson#gson;2.7 in bintray/jcenter
	found com.google.code.findbugs#jsr305;3.0.1 in bintray/jcenter
	found com.google.jsinterop#jsinterop-annotations;1.0.0 in bintray/jcenter
	found com.google.auto.value#auto-value;1.4.1 in bintray/jcenter
	found org.apache.ant#ant;1.9.7 in bintray/jcenter
downloading https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20181210/closure
...
	---------------------------------------------------------------------
	|                  |            modules            ||   artifacts   |
	|       conf       | number| search|dwnlded|evicted|| number|dwnlded|
	---------------------------------------------------------------------
	|      runtime     |   16  |   14  |   14  |   2   ||   16  |   16  |
	---------------------------------------------------------------------

Je me sens comme cela.

> ls -l
total 8
drwxr-xr-x 1 racine racine 512 23 décembre 21:37 lib
-rw-r--r--1 racine racine 4438 23 décembre 21:37 marun.json

> ls -l lib
total 18980
-rw-r--r--2 racine racine 3482 26 février 2015 animal-sniffer-annotations-1.14.jar
-rw-r--r--2 racine racine 2036195 12 avril 2016 fourmi-1.9.7.jar
-rw-r--r--2 root root 74703 3 novembre 2013 args4j-2.0.26.jar
-rw-r--r--2 racine racine 1504726 7 avril 2017 auto-value-1.4.1.jar
-rw-r--r--2 racine racine 343222 6 mai 2016 vérificateur-qual-2.0.0.jar
-rw-r--r--2 racine racine 189289 31 octobre 04:55 closure-compiler-externs-v20181028.jar
-rw-r--r--2 root root 10248761 13 décembre 03:35 closure-compiler-v20181210.jar
-rw-r--r--2 root root 13162 21 avril 2018 erreur_prone_annotations-2.3.1.jar
-rw-r--r--2 root root 231952 15 juin 2016 gson-2.7.jar
-rw-r--r--2 racine racine 2734339 24 mai 2018 goyave-25.1-jre.jar
-rw-r--r--2 root root 8764 27 juillet 2016 j2objc-annotations-1.1.jar
-rw-r--r--2 root root 4075 29 juillet 2016 jsinterop-annotations-1.0.0.jar
-rw-r--r--2 root root 19943 9 octobre 2015 jsr305-3.0.1.jar
-rw-r--r--2 racine racine 1304415 7 septembre 2016 protobuf-java-3.0.2.jar

Vous pouvez également l'exécuter avec marun run. Closure Compiler exécute, par exemple, com.google.javascript.jscomp.CommandLineRunner, mais c'est un peu intelligent, vous pouvez donc le faire pour trouver main avec le nom abrégé.

> marun run CommandLineRunner
The compiler is waiting for input via stdin.

Contenu

Comme vous pouvez le voir dans le message affiché, il s'agit presque de Apache Ivy. Cela ne semblait pas si difficile à écrire par moi-même juste pour résoudre les dépendances, mais le facteur décisif était qu'il semblait y avoir des pièges et que gradle l'utilisait dans le passé. (Il semble qu'ils résolvent leurs propres dépendances maintenant)

J'ai téléchargé le fichier jar minimum requis pour démarrer Ivy avec Python, puis j'ai inclus Ivy avec Ivy et essayé de résoudre à nouveau la dépendance.

De plus, le contenu de marun.json est comme ça, seules quelques données d'analyse sont incluses.

marun.json


{
    "1545568648": {
        "mains": [
            "com.google.javascript.jscomp.CommandLineRunner", 
            "com.google.javascript.jscomp.LinterMain", 
            "org.kohsuke.args4j.Starter", 
            "org.apache.tools.ant.Diagnostics", 
            "org.apache.tools.ant.taskdefs.KeySubst", 
            "org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc", 
            "org.apache.tools.ant.taskdefs.optional.jlink.jlink", 
            "org.apache.tools.ant.util.ProcessUtil"
        ], 
        "dependencies": {
            "com.google.code.gson:gson": {
                "cache": "/var/lib/marun/ivy/com.google.code.gson/gson/jars/gson-2.7.jar", 
                "name": "gson-2.7.jar", 
                "revision": "2.7"
            }, 
...
        },
        "install": [
            "com.google.javascript:closure-compiler:+"
        ]
    },
    "context": [
        1545568648
    ]
}

Comme vous pouvez le voir dans le fichier json, il permet également de sauvegarder et d'exécuter la version de la bibliothèque, mais il télécharge essentiellement tous les jars dans lib, vous pouvez donc l'exécuter avec java -cp lib / *.

fin

Donc, je m'inquiétais de la façon de déployer Java, alors j'ai essayé de créer un outil de déploiement qui comble le vide. Je pense qu'il y a des situations addictives, alors utilisez-le si vous le souhaitez. Ne vous attendez pas à la perfection pour le moment. (Je veux faire de mon mieux)

Aussi, si vous n'avez pas à créer un tel outil, ou si vous souhaitez le faire, veuillez nous en informer!

Recommended Posts

J'ai créé un nouvel outil de déploiement Java
J'ai créé un outil Diff pour les fichiers Java
J'ai créé une application shopify @java
J'ai créé un outil de génération package.xml.
J'ai créé un programme de jugement des nombres premiers en Java
J'ai créé un jeu Janken en Java (CLI)
J'ai fait un jeu de problèmes de calcul simple en Java
J'ai créé un outil de vérification pour le module de version
J'ai fait une roulette à Java.
J'ai créé une application de chat.
J'ai créé un Wrapper qui appelle KNP depuis Java
[Débutant] J'ai créé un programme pour vendre des gâteaux en Java
J'ai créé un Dockerfile pour démarrer Glassfish 5 en utilisant Oracle Java
J'ai créé une interface graphique avec Swing
J'ai fait une annotation en Java.
J'ai créé une application correspondante (application Android)
[Android] J'ai créé une application de podomètre.
Création d'une méthode pour demander Premium Friday (version Java 8)
J'ai créé un outil pour afficher la différence du fichier CSV
[Ruby] J'ai créé un simple client Ping
J'ai essayé le nouveau yuan à Java
J'ai fait une mort risquée avec Ruby
J'ai créé un plug-in pour IntelliJ IDEA
J'ai créé une application Janken avec kotlin
J'ai créé une application Janken avec Android
J'ai créé une classe qui peut utiliser JUMAN et KNP de Java
[LINE BOT] J'ai créé un Ramen BOT avec Java (Maven) + Heroku + Spring Boot (1)
Les nouveaux ingénieurs Java peuvent lire une série rafraîchissante!
J'ai créé StringUtils.isBlank
04. J'ai fait un frontal avec SpringBoot + Thymeleaf
J'ai fait de l'art de la mosaïque avec des images Pokemon
java j'ai essayé de casser un simple bloc
J'ai essayé de développer un outil de gestion des effectifs
Je l'ai fait en Java pour toujours rendre (a == 1 && a == 2 && a == 3) vrai
J'ai essayé de frapper une méthode Java d'ABCL
Je voulais que (a == 1 && a == 2 && a == 3) vrai en Java
J'ai créé une application de visualisation qui affiche le PDF
J'ai créé un conteneur Docker pour exécuter Maven
J'ai créé une bibliothèque d'extension Ruby en C
[Rails] J'ai créé une fonction de brouillon en utilisant enum
java1.8 nouvelles fonctionnalités
Apprendre Java avec Progate → Je vais vous expliquer parce que j'ai moi-même créé un jeu de base
J'ai créé un robot LINE avec Rails + heroku
J'ai écrit un programme de factorisation prime en Java
J'ai essayé de casser le bloc avec java (1)
J'ai essayé d'exécuter Java dans un terminal Mac
J'ai fait un portfolio avec Ruby On Rails
J'ai créé une image Docker pour la version japonaise de SDAPS
J'ai fait une méthode pour demander la prime vendredi
[Ruby] J'ai fait un robot avec de l'anémone et du nokogiri.
J'ai fait un chat de dessin "chat de peinture 8 bits" avec WebAssembly
J'ai essayé de créer une compétence Clova en Java
Essayez Easy Ramdom, un outil de test PropertyBase pour Java
J'ai essayé d'utiliser Log4j2 sur un serveur Java EE
J'ai créé un serveur et un client Restful au printemps.
J'ai créé une bibliothèque qui fonctionne comme un onglet dans Safari !!
J'ai essayé OCR de traiter un fichier PDF avec Java
J'ai créé une bibliothèque pour afficher des tutoriels sur Android.