Ich habe ein neues Java-Bereitstellungstool erstellt

Java-Bereitstellungsproblem

Was machen Sie plötzlich mit der Java-Bereitstellung?

Natürlich gibt es am Ende viele Möglichkeiten zur Bereitstellung. Es gibt, aber in der Skriptsprache, ein leichtes Projekt, das mit gem, pip, npm usw. geklont werden kann, um einige Abhängigkeiten zu lösen, aber wenn es um Java geht, wird das Fett des fetten Glases überraschenderweise gelöscht oder die JAR-Datei Es wird ein etwas subtiler Stil sein, wie das manuelle Generieren und Ersetzen. (Das ist nicht der Fall! Bitte lassen Sie mich wissen, wenn Sie eine gute Lösung haben)

Erstens scheint es, dass Sie erst zu einem solchen Zeitpunkt in Java schreiben sollten, aber es wird gesagt, dass Java (oder JVM-Sprache) nur geringfügig erforderlich ist, z. B. die Wiederverwendung von Code-Assets mit peripheren Tools oder die Durchführung einer parallelen Berechnung mit ein wenig Multithreading. Existiert immernoch.

Bereitstellungsmethode in Java

Betrachten wir zunächst die vorhandene Java-Bereitstellungsmethode.

Quellcodeübertragung

Es ist eine Methode, um zu versuchen, etwas mit der gleichen Idee wie die Skriptsprache zu tun. Kopieren Sie den Quellcode mit git oder einem Tool, lösen Sie die Abhängigkeit mit gradle (im Folgenden einschließlich maven / sbt / usw.) auf dem Ausführungsserver auf und erstellen Sie lokal. In einigen Fällen wird es so ausgeführt, wie es mit gradle ist.

Vorteil

Nachteil

Es ist keine schlechte Methode, aber es ähnelt eher einem Entwicklungsserver als einem Bereitstellungsziel, da es den gesamten Satz enthält. Es ist auch schwierig festzustellen, dass es auf dem Server nicht geändert wurde. Ich mache mir Sorgen, dass ich es nicht weiß, wenn ich mich ändere und baue und dann jemand versucht, etwas zu tun und zu einem anderen Zweig zu wechseln.

Übertragung von Klassendateien

Dies ist eine Methode, um eine .class-Datei, bei der es sich um eine Zusammenstellung einer .java-Datei handelt, auf einen Server zu übertragen und auszuführen.

Vorteil

Nachteil

Ist es eine Methode? Ich habe es getan, als ich anfing, Java zu verwenden. Es ist einfach, weil Sie nur die von der IDE erstellte Datei kopieren. Anstatt es bereitzustellen, ist es nur eine Möglichkeit, es auf einem Server auszuführen. Wenn es sich um eine Skriptsprache handelt, ist dies wie das Kopieren mit .zip oder .tar. Dies ist die schlechteste Methode, wenn Sie den tatsächlichen Betrieb in Betracht ziehen, z. B. nicht alle .classes zu haben, die Version natürlich nicht gut zu kennen oder zu mischen.

Generierung von JAR-Dateien

Sammeln Sie .class-Dateien mit dem Befehl IDE oder jar oder übertragen Sie von gradle generierte .jar-Dateien auf den Server. Übertragen Sie auch die JAR-Dateien der abhängigen Bibliotheken.

Vorteil

Nachteil

Es ist eine legitime Methode für seine primitive Natur. In Bezug auf die Implementierung entspricht dies dem Senden einer .class-Datei im Zip-Format, ist jedoch äußerst einfach zu handhaben, da verschiedene Java-Tools dies unterstützen.

Sie können Quellcode, Memos, Dokumente usw. einfügen. Ich denke, es ist immer noch nützlich, wenn Sie es nicht verwalten können. Es ist jedoch schwierig, alle JAR-Dateien mit Abhängigkeiten zu erfassen. Und verschiedene Versionen von .jar werden gemischt und es wird Jar Hölle statt DLL Hölle ...

In ein fettes Glas geben

Die königliche Methode. Erstellen Sie alle abhängigen Bibliotheken als eine ausführbare JAR neu. Da wir main definieren, können wir Folgendes tun:

> java -jar xxxx.jar arg1 arg2

Kürzlich (?) Scheint als Überglas oder Schattenglas bezeichnet zu werden.

Vorteil

Nachteil

Dies ist eine übliche Technik. Das Gute ist, dass Sie nur eine einzelne Datei übertragen können. Es ist alles in, so dass Sie sich keine Sorgen machen müssen, dass es teilweise aktualisiert und schrecklich ist, und Sie müssen sich keine Sorgen machen, die Hauptklasse zu vergessen.

Persönlich ist es zu fett (verdammt groß), und wenn ich nur die Produktionsumgebung betrachte, weiß ich nicht sofort den Namen der verwendeten Bibliothek oder der Hauptklasse, die ich leite, sodass ich nichts sagen kann, wenn ich sie nicht entpacke. Es entspricht nicht wirklich meinem Geschmack, wenn ich auf einem Server laufe. Vielleicht ist es besser, unter den richtigen Namensregeln zu arbeiten.

Es ist ein bisschen traurig, weil ich manchmal Fat Jar wähle, weil es schwierig ist, Abhängigkeits-JAR-Dateien wie Gradle zu sammeln. Es scheint nicht so häufig zu sein, aber die Abhängigkeitsbibliothek ist [auf diese Weise](https://stackoverflow.com/questions/23109276/gradle-task-to-put-jars-from-maven-repository-into-project- Es wird von lib-folder gesammelt).

In einer Kriegsakte zusammenstellen

Dasselbe können Sie mit fetten Gläsern mit Kriegs- und Ohrfeilen tun, die Sie außerhalb des Webs selten sehen. Krieg ist möglicherweise besser geeignet, da es eine genauere Steuerung ermöglicht, z. B. das Einschließen der Anwendungseinstellungsdatei, das Ausschließen aus dem Klassenpfad.

Vorteil

Nachteil

Ich denke, die Kriegsdatei ist nützlich, wenn Sie viele Java EE-Umgebungen haben. Wenn es sich um eine Kriegsdatei handelt, kann dies auch dann akzeptabel sein, wenn die Dateigröße etwas groß ist (Bias).

Docker-Bild

Erstellen Sie ein Image, indem Sie eine Ausführungsumgebung im Docker-Container erstellen. Ist das Java Docker-Image schwer? Nein, Alphine Linux / musc libc / Jigsaw macht es einigermaßen kompakt.

Heutzutage können Sie mit Maven / Gradle auch gleichzeitig ein Docker-Image mit Google / Jib erstellen.

Vorteil

Nachteil

Es wird von nun an der Favorit sein. Die Docker-Unterstützung von Java schreitet ebenfalls voran, und man kann sagen, dass die leicht verständlichen Probleme fast verschwunden sind. Es verwaltet auch Versionen, und Sie müssen sich keine Sorgen machen, dass Sie an das lokale Java-Verhalten gebunden sind.

Auf der anderen Seite ist es Docker ... Es gibt einige Situationen, die für Docker nicht geeignet sind, und es ist eine Schande, eine JVM, die den Speicher relativ einfach steuern kann, in einen Container zu legen.

Denken Sie an eine neue Bereitstellungsmethode

Mit Blick auf verschiedene Dinge möchten wir die folgenden Probleme für eine ideale Bereitstellung lösen.

Welches Tool erfüllt diese Anforderung? Übrigens, wenn Sie sich andere Sprachen ansehen, können Sie diese normalerweise mit gem, pip, npm usw. bereitstellen. Der Hauptcode kann git-geklont oder aus einem privaten Repository bereitgestellt werden. Versionen werden im Repository verwaltet, und Sie können anhand der Produktionsumgebung sehen, was auf einen Schlag passiert ist.

Ist das bei Java nicht der Fall? Vorausgesetzt, das Repository verfügt zumindest über ein Maven-Repository. Ich kann keinen Git-Klon erstellen, für den eine Kompilierung erforderlich ist, aber ich bin der Meinung, dass die Unterstützung für private Repositorys leistungsfähiger ist als für andere Sprachen. Danach wäre es schön, wenn es ein Werkzeug gäbe. .. ..

Deshalb habe ich es geschafft.

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

Ein Tool zum Herunterladen von Zielartefakten aus dem Maven-Repository beim Auflösen von Abhängigkeiten.

> marun install com.example:example:1.0.1

Vorteil

Nachteil

gradle und maven können Abhängigkeiten auflösen, aber sie sind großartig, weil sie nur Build-Tools sind und Abhängigkeiten in Abhängigkeitsbibliotheken (Artefakten) auflösen können, aber sie sind gut für den Umgang mit ihnen. Es gibt keine Funktion, um nur Artefakte herunterzuladen. Es gibt ein Tool namens Apach Ivy, das nur auf das Auflösen von Abhängigkeiten im Maven-Repository spezialisiert ist, aber auch zum Erstellen in Kombination mit Apache Ant. Es wird hauptsächlich als nur für Ivy verwendet betrachtet, und Ivy.xml muss geschrieben werden, um es alleine zu verwenden.

Also habe ich Apache Ivy verwendet, um ein Tool zu erstellen, das nur die Zielartefakte und ihre Abhängigkeiten herunterlädt.

Ich benötige ein privates Repository, aber jetzt zum Beispiel Maven-Publish-Plugin und Aws-Maven-Plugin suzutt / items / bf1e8a8e425a9077b96c) erleichtert das Erstellen eines Maven-Repositorys auf Amazon S3.

Installation

Es ist nicht gut, zuerst schwierig zu sein, deshalb wird es mit pip installiert. Der Befehlszeilenteil ist Python2, damit es so gut wie möglich mit dem System Python funktioniert.

> sudo pip install marun

init Vorerst initialisieren. Für die Ausführung ist Java erforderlich. Installieren Sie es daher zuerst.

> sudo marun init
configuration file is not found!
Your Maven Repository URL []: s3://your_repository
S3 Access Key []:(Geben Sie den Zugangsschlüssel ein)
S3 Secret Key []:(Geben Sie den geheimen Schlüssel ein)

Zusätzlich zu s3 kann es auch mit http / https verwendet werden. Wenn Sie es eingeben, wird eine Einstellungsdatei * /etc/marun.conf * erstellt.

Übrigens wird Ivy sein Bestes tun, um die Abhängigkeiten von Marun selbst so herunterzuladen. Aufgrund von Amazon S3 gibt es viele Abhängigkeiten von JAR-Dateien. Tauchen Sie ein in * / var / lib / marun *.

Ivy arbeitet hart


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   |
	---------------------------------------------------------------------

Versuchen Sie es mit

Es ist eine gute Idee, etwas in Ihr privates Repository herunterzuladen und auszuführen, aber hier werde ich versuchen, den Google Closure Compiler herunterzuladen.

> 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  |
	---------------------------------------------------------------------

Ich fühle mich so.

> ls -l
total 8
drwxr-xr-x 1 Wurzel Wurzel 512 23. Dezember 21:37 lib
-rw-r--r--1 Wurzel Wurzel 4438 23. Dezember 21:37 marun.json

> ls -l lib
total 18980
-rw-r--r--2 Wurzel Wurzel 3482 26. Februar 2015 Tier-sniffer-annotations-1.14.jar
-rw-r--r--2 Wurzel Wurzel 2036195 12. April 2016 Ameise-1.9.7.jar
-rw-r--r--2 root root 74703 3. November 2013 args4j-2.0.26.jar
-rw-r--r--2 root root 1504726 7. April 2017 auto-value-1.4.1.jar
-rw-r--r--2 root root 343222 6. Mai 2016 checker-qual-2.0.0.jar
-rw-r--r--2 Wurzel Wurzel 189289 31. Oktober 04:55 closure-compiler-externs-v20181028.jar
-rw-r--r--2 root root 10248761 13. Dezember 03:35 closure-compiler-v20181210.jar
-rw-r--r--2 root root 13162 21. April 2018 Fehler_prone_annotations-2.3.1.jar
-rw-r--r--2 root root 231952 15. Juni 2016 gson-2.7.jar
-rw-r--r--2 Wurzel Wurzel 2734339 24. Mai 2018 Guave-25.1-jre.jar
-rw-r--r--2 root root 8764 27. Juli 2016 j2objc-annotations-1.1.jar
-rw-r--r--2 root root 4075 29. Juli 2016 jsinterop-annotations-1.0.0.jar
-rw-r--r--2 root root 19943 9. Oktober 2015 jsr305-3.0.1.jar
-rw-r--r--2 root root 1304415 7. September 2016 protobuf-java-3.0.2.jar

Sie können es auch mit "marun run" ausführen. Der Closure Compiler führt beispielsweise "com.google.javascript.jscomp.CommandLineRunner" aus, ist jedoch etwas clever. Sie können dies also tun, um main mit dem abgekürzten Namen zu finden.

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

Inhalt

Wie Sie in der angezeigten Nachricht sehen können, handelt es sich fast um Apache Ivy. Es schien nicht so schwer zu sein, alleine zu schreiben, nur um die Abhängigkeiten aufzulösen, aber der entscheidende Faktor war, dass es einige Fallstricke zu geben schien und dass Gradle es in der Vergangenheit benutzte. (Es scheint, dass sie jetzt ihre eigenen Abhängigkeiten lösen)

Ich habe die minimale JAR-Datei heruntergeladen, die zum Starten von Ivy mit Python erforderlich ist. Danach habe ich Ivy mit Ivy aufgenommen und versucht, die Abhängigkeit erneut aufzulösen.

Außerdem ist der Inhalt von marun.json so, dass nur wenige Analysedaten enthalten sind.

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
    ]
}

Wie Sie in der json-Datei sehen können, hilft es auch beim Speichern und Ausführen der Bibliotheksversion, lädt jedoch im Wesentlichen nur alle Jars in lib herunter, sodass Sie sie mit java -cp lib / * ausführen können.

Ende

Ich war also besorgt darüber, wie Java bereitgestellt werden soll, und habe versucht, ein Bereitstellungstool zu erstellen, das die Lücke schließt. Ich denke, es gibt einige Situationen, denen ich verfallen bin, also benutze sie bitte, wenn du magst. Erwarten Sie vorerst keine Perfektion. (Ich möchte mein Bestes geben)

Wenn Sie ein solches Tool nicht erstellen müssen oder dies tun möchten, lassen Sie es uns bitte wissen!

Recommended Posts

Ich habe ein neues Java-Bereitstellungstool erstellt
Ich habe ein Diff-Tool für Java-Dateien erstellt
Ich habe eine shopify App @java erstellt
Ich habe ein Tool zur Generierung von package.xml erstellt.
Ich habe ein Programm zur Beurteilung von Primzahlen in Java erstellt
Ich habe ein Janken-Spiel in Java (CLI) gemacht.
Ich habe ein einfaches Berechnungsproblemspiel in Java gemacht
Ich habe ein Check-Tool für das Release-Modul erstellt
Ich habe ein Roulette in Java gemacht.
Ich habe eine Chat-App erstellt.
Ich habe einen Wrapper erstellt, der KNP von Java aus aufruft
[Anfänger] Ich habe ein Programm zum Verkauf von Kuchen in Java erstellt
Ich habe eine Docker-Datei erstellt, um Glassfish 5 mit Oracle Java zu starten
Ich habe mit Swing eine GUI erstellt
Ich habe eine Anmerkung in Java gemacht.
Ich habe eine passende App erstellt (Android App)
[Android] Ich habe eine Schrittzähler-App erstellt.
Erstellt eine Methode zum Anfordern von Premium Friday (Java 8-Version)
Ich habe ein Tool erstellt, um den Unterschied zwischen CSV-Dateien auszugeben
[Ruby] Ich habe einen einfachen Ping-Client erstellt
Ich habe das neue Yuan-Problem in Java ausprobiert
Ich habe mit Ruby einen riskanten Würfel gemacht
Ich habe ein Plug-In für IntelliJ IDEA erstellt
Ich habe eine Janken App mit Kotlin gemacht
Ich habe eine Janken App mit Android gemacht
Ich habe eine Klasse erstellt, die JUMAN und KNP aus Java verwenden kann
[LINE BOT] Ich habe einen Ramen BOT mit Java (Maven) + Heroku + Spring Boot (1) gemacht.
Neue Java-Ingenieure können eine erfrischende Serie lesen!
Ich habe StringUtils.isBlank gemacht
04. Ich habe mit SpringBoot + Thymeleaf ein Frontend gemacht
Ich habe Mosaikkunst mit Pokemon-Bildern gemacht
Java Ich habe versucht, einen einfachen Block zu brechen
Ich habe versucht, ein Personalmanagement-Tool zu entwickeln
Ich habe Java gemacht, um (a == 1 && a == 2 && a == 3) immer wahr zu machen
Ich habe versucht, eine Java-Methode von ABCL zu verwenden
Ich wollte (a == 1 && a == 2 && a == 3) in Java wahr machen
Ich habe eine Viewer-App erstellt, die PDF anzeigt
Ich habe einen Docker-Container erstellt, um Maven auszuführen
Ich habe eine Ruby-Erweiterungsbibliothek in C erstellt
[Rails] Ich habe eine Entwurfsfunktion mit enum erstellt
Java1.8 neue Funktionen
Lerne Java mit Progate → Ich werde es erklären, weil ich selbst ein einfaches Spiel gemacht habe
Ich habe einen LINE Bot mit Rails + Heroku gemacht
Ich habe ein Primfaktorisierungsprogramm in Java geschrieben
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, Java in einem Mac-Terminal auszuführen
Ich habe mit Ruby On Rails ein Portfolio erstellt
Ich habe ein Docker-Image für die japanische Version von SDAPS erstellt
Ich habe eine Methode entwickelt, um nach Premium Friday zu fragen
[Ruby] Ich habe einen Crawler mit Anemone und Nokogiri gemacht.
Ich habe mit WebAssembly einen Zeichnungschat "8bit Paint Chat" erstellt
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
Probieren Sie Easy Ramdom, ein PropertyBase-Testtool für Java
Ich habe versucht, Log4j2 auf einem Java EE-Server zu verwenden
Ich habe im Frühjahr einen Restful-Server und -Client erstellt.
Ich habe eine Bibliothek erstellt, die in Safari wie ein Tab funktioniert !!
Ich habe versucht, mit OCR eine PDF-Datei mit Java zu verarbeiten
Ich habe eine Bibliothek zum Anzeigen von Tutorials auf Android erstellt.