2016-07-20 44 views
6

Ich habe ein Java-Projekt mit ~ 2400 Klassen. Sie werden meist mithilfe von XJC aus einem XML-Schema mit einigen Erweiterungen generiert.Java-Kompilierungsgeschwindigkeit

Die Zusammenstellung dauert sehr lange, ~ 20 Minuten, und ich frage mich, ob ich etwas tun kann, um das zu verbessern?

Ein ähnliches Projekt hat etwa die Hälfte der generierten Klassen, aber mehrere handgeschriebene Klassen für insgesamt ~ 3000 Klassen. Dies ergibt eine stomabarable 2-5 Minuten.

Ich verwende Java 8 (1.8.0_92 unter Windows) zum Kompilieren, aber mit Quell- und Zielversion 6 (daher ist das Problem nicht das langsame System auf Java 8). Die Kompilierung erfolgt mit Maven 3.3.3 mit Maven-Compiler-Plugin 3.5.1. Ich verzweifle den Compiler von Maven und benutze maxmem 2048m.

Die generierten Klassen sind im Allgemeinen klein, aber ich habe einen riesigen Besucher, der alle generierten Klassen anfasst (also gibt es eine Eins für alle und eine alle für eine Abhängigkeit). Ich kann nicht wirklich etwas dagegen tun.

Der Wechsel von "mvn clean install" zu "mvn install" (oder einfach "mvn compile") hilft, aber das ist nicht immer eine Option (im Grunde verschraubt sich Eclipse mit kompilierten Dateien, damit Tests einwandfrei laufen , Ich muss während der Ausführung von Tests von dem Befehl reinigen, wie vor dem Commit).

Ich habe keine Hintergrundprozesse, die Dateien der Kompilierungseinheit beobachten (wie Eclipse/SourceTree), aber ich habe einen Virenscanner (den ich nicht ausschalten kann). Es scheint, dass die meiste Zeit von Javac verbracht wird.

Gibt es in javac etwas, das in der Anzahl der gegenseitig abhängigen Klassen superlinear ist? Oder gibt es einen Weg, wie ich diese Kompilierungszeiten umgehen kann?

E: Ich habe einen Vorschlag zum Laufen Maven Multi-Threaded; Leider habe ich das schon ausprobiert, und es hilft hier nicht wirklich, da es ein Einzelmodul-Projekt mit vielen voneinander abhängigen Klassen ist.

E2: Ich habe das Projekt in ein Modul mit nur dem JAXB-Code und ein anderes mit dem Hauptcode aufgeteilt. Es stellte sich heraus, dass der JAXB-Code nicht der Schuldige war. Ich lief die Tesla Maven Profiler und es bestätigte gerade die Kompilierung ist das Problem; relevanter Teil:

org.apache.maven.plugins:maven-compiler-plugin:3.5.1 (default-compile) 18m 48s 
org.apache.maven.plugins:maven-compiler-plugin:3.5.1 (default-testCompile) 14s 770ms 
org.apache.maven.plugins:maven-surefire-plugin:2.12.4 (default-test) 1m 51s 
org.apache.maven.plugins:maven-war-plugin:2.0.1 (default-war) 14s 635ms 

Ich bin völlig in Ordnung mit der Dauer der letzten drei.

Dies sind nur 1000 Java-Klassen, die alle von einem allgemeinen Besucher stammen, der mit JAXB generiert wurde. Meine Kompilierung Konfiguration:

   <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <version>3.5.1</version> 
        <configuration>   
          <fork>true</compiler> 
          <source>${compileSource}</source> 
          <target>${compileSource}</target> 
          <meminitial>512m</meminitial> 
          <maxmem>2048m</mexmem> 
          <encoding>UTF-8<eencoding> 
        </configuration> 
       </plugin> 

(compileSource ist 1,6)

+0

Re "Eclipse dreht sich mit kompilierten Dateien": Um Konflikte zwischen Maven und Eclipse zu vermeiden, kann viel durch selektives Aktivieren/Deaktivieren von "Automatisch erstellen" in Eclipse verbessert werden: Stellen Sie sicher, dass immer nur ein Werkzeug an Ihren Projekten arbeitet. Nachdem maven ausgeführt wurde, vergessen Sie nicht, Ressourcen in Eclipse zu aktualisieren. –

Antwort

4

Stellt sich heraus, ist das Problem wirklich in Java. JavaC kann Klassen mit stark überladenen Methoden nicht sehr gut verarbeiten (http://mail.openjdk.java.net/pipermail/compiler-dev/2013-May/006339.html).

Ich erzeugte einen Besucher, der eine Besuchs (...) -Methode für jede Klasse (1100+) erzeugte, was die Kompilation jedes Derivats mehrere Sekunden in Anspruch nahm. Da ich Hunderte dieser Methoden hatte, addierte sich das alles.

Mein Besucher wurde mithilfe von jaxb-visitor (https://github.com/massfords/jaxb-visitor) generiert und das Problem behoben, indem der Typname in generierte Methoden mit meinem eigenen Fork des Codes (https://github.com/klafbang/jaxb-visitor) eingefügt wurde.

Die Zusammenstellungszeit ging von 40 Minuten auf 2 Minuten zurück.

2

Sie können Multi-Thread-Option seit 3 ​​eingeführt, nicht sicher, wie es in Ihrem Fall verbessern können, da Sie einzelne Modul haben, können Sie Ihre Testläufe sein sein etwas schneller, aber Sie können jedoch überprüfen Sie mit dieser Option

mvn clean install -T5C 

Hier wird die link die parallel Build

+0

Danke für den Vorschlag. Ich habe vergessen zu erwähnen, ich habe bereits einen Multi-Thread-Build versucht - ich werde meine Frage bearbeiten. Leider, wie Sie auch vermuten, hilft es hier nicht wirklich, da das Problem wirklich mit der Kompilierung der 2400 voneinander abhängigen Klassen ist. – klafbang

1

Ein Weg t erklären o löse dein Problem, könnte sein, dein Maven-Projekt aufzuteilen und eines nur für generierte Klassen zu erstellen, dieses muss nicht jedes Mal neu erstellt werden, nur wenn xsd sich ändert.Und mach es abhängig von dem anderen Projekt.

+0

Manchmal übersieht man die einfachsten Lösungen ... Danke für den Vorschlag! Werde das versuchen und zurückkommen, ob es das Problem löst. – klafbang

+0

Dies - nach viel Refactoring - hat das Problem leider nicht gelöst. Mein JAXB-Code wird jetzt in "nur" 3-4 Minuten kompiliert, während mein Anwendungscode die meiste Zeit benötigt (20-25 Minuten). – klafbang

+0

Sie können Maven in einer Konsole mit -e starten, um die Details zu protokollieren und vielleicht sehen Sie, wo sie die meiste Zeit verbringen. Mit diesem Hinweis können Sie das Projekt aufteilen, um nur den Teil zu kompilieren, den Sie benötigen. –