2013-09-30 4 views
7


Was ist der einfachste Weg (Tool?), Um nicht verwendete Gläser aus meinem Java (Ant) -Projekt zu entfernen. Unser Projekt ist wirklich riesig geworden, und wir wollen aufräumen. Es gibt mehrere jars, die dem classpath hinzugefügt werden, aber nicht alle werden für compile/run verwendet. Gibt es eine Möglichkeit, die unnötigen JARs zu identifizieren, indem Sie ein Dienstprogramm über die Befehlszeile ausführen?
Hinweis: Wir möchten nicht den langwierigen Prozess des Entfernens eines oder mehrerer Gläser folgen, dann kompilieren/ausführen, um zu testen, ob diese erforderlich sind oder nicht.entfernen Sie nicht verwendete Gläser aus dem Projekt

Antwort

9

Dies ist, was ich schließlich
Ich benutzte JBOSS TattleTale (http://www.jboss.org/tattletale), um nicht verwendete Gläser zur Kompilierzeit zu identifizieren (Es gemeldet 17 Gläser als unbenutzt).
Dann habe ich für jedes Jar in dieser Liste eine String-Suche in meinem Projekt durchgeführt, um herauszufinden, ob die höchste Package-Ebene des Jars irgendwo verwendet wurde (dies ist ein Versuch zu sehen, ob eine zu diesem Jar gehörende Klasse durch Reflektion geladen wurde)).
So konnte ich erfolgreich 6 Gläser aus meinem Projekt eliminieren.
Da die Anzahl der nicht verwendeten Jars zur Kompilierungszeit gering war, war dieser Ansatz schnell.

+0

Tattle Märchen Regeln –

+0

cool, danke für den Vorschlag. Können Sie ein kleines Beispiel dafür geben, wie Sie es verwenden? –

+0

Kann Tattletale außerhalb von JBOSS verwendet werden, zum Beispiel mit Tomcat? – user7294900

4

Wenn es eine bessere Lösung dafür gibt, würde ich es gerne hören.

Das Problem ist, dass selbst wenn ein Gefäß nicht zu kompilieren benötigt wird, könnte es zu Laufe benötigt werden. Und dieses "Bedürfnis" könnte transitiv sein. EG: Ein Glas, das Sie verwenden, benötigt ein Glas, das Sie nicht verwenden und nur zur Laufzeit. Wie auch die Art der Laufzeitfehler, sie werden nur angezeigt, wenn Sie versuchen, den Code auszuführen. Im schlimmsten Fall passiert das möglicherweise erst, wenn Sie in der Produktion laufen.

Die beste Lösung, die ich kenne, ist genau das, was Sie nicht tun wollen: "Entfernen Sie ein oder mehrere Gläser, dann kompilieren Sie, um zu testen, ob diese erforderlich sind oder nicht".

2

Remove -> Test -> entfernen -> Test -> Entfernen -> Hope you :)

Projekt ändern genießen nur jar Sie wollen verwenden Maven und auszuwählen. Für mich ist das der einfachste Weg.

1

Wie tieTYT in seiner Antwort bemerkt, werden viele Gläser nur zur Kompilierzeit benötigt. (zum Beispiel jdbc implementation jars)

Ein anderer Ansatz könnte sein, einen Java-Agenten zu schreiben und alle Klassennamen zu sammeln. Sie können diese Klassennamen dann zu jar zuordnen und prüfen, ob keine Jars benötigt werden.

Beispiel-Agent

package com; 

import java.lang.instrument.ClassFileTransformer; 
import java.lang.instrument.IllegalClassFormatException; 
import java.lang.instrument.Instrumentation; 
import java.security.ProtectionDomain; 


public class NameAgent { 


    public static void premain(String agentArgs, Instrumentation inst) { 

     inst.addTransformer(new Tranformer(), true); 
    } 


    static class Tranformer implements ClassFileTransformer { 

     @Override 
     public byte[] transform(ClassLoader loader, 
           String className, 
           Class<?> classBeingRedefined, 
           ProtectionDomain protectionDomain, 
           byte[] classfileBuffer) throws IllegalClassFormatException { 
      System.out.println("loading-class:" + className); 
      return classfileBuffer; 
     } 
    } 

} 

build.xml ... für ant

<project name="namedump" default="dist" basedir="."> 

    <property name="src" value="src"/> 
    <property name="build" value="build"/> 
    <property name="dist" value="dist"/> 

    <target name="init"> 
     <mkdir dir="${build}"/> 
     <mkdir dir="${dist}"/> 
    </target> 

    <target name="compile" depends="init"> 
     <javac srcdir="${src}" destdir="${build}" optimize="true" includeantruntime="false"/> 
    </target> 

    <target name="dist" depends="compile"> 
     <jar jarfile="${dist}/namecollector.jar"> 
      <fileset dir="${build}"/> 
       <manifest > 
        <attribute name="Premain-Class" value="com.NameAgent" /> 
        <attribute name="Can-Redefine-Classes" value="true" /> 
        <attribute name="Can-Retransform-Classes" value="true" /> 

       </manifest> 
     </jar> 
     <pathconvert property="absdist" dirsep="/"> 
      <path location="${dist}"/> 
     </pathconvert> 
     <echo> 
      To use, add the following to the JVM command-line options. 

      -javaagent:${absdist}/namecollector.jar 
     </echo> 
    </target> 

    <target name="clean"> 

     <delete dir="${build}"/> 
     <delete dir="${dist}"/> 
    </target> 
</project> 

Einen weiteren Ansatz, den wir in Fenstern versuchen die Tatsache, wurde mit, dass die Gläser verschlossen werden, wenn Klassen geladen werden. Führen Sie die Anwendung aus, und versuchen Sie, aus dem Laufzeitbereich zu löschen. Wenn es verwendet wurde, sollte Löschen fehlschlagen. Nicht sicher, wie sicher das ist - ich weiß, dass es unter Linux nicht funktioniert, die Dateien können ohne Probleme gelöscht werden.

+0

Danke für Ihre Antwort, werde es beim nächsten Mal versuchen! – flowerpot

Verwandte Themen