2013-09-30 14 views
7


Co to jest najprostszy sposób (narzędzie?) Do usunięcia nieużywanych słoików z mojego projektu java (ant). Nasz projekt stał się naprawdę ogromny i chcemy zrobić porządek. Istnieje kilka słoików dodanych do ścieżki klasy, ale nie wszystkie są używane do kompilacji/uruchamiania. Czy istnieje sposób na identyfikację niepotrzebnych słoików poprzez uruchomienie narzędzia z linii poleceń?
Uwaga: nie chcemy podążać za żmudnym procesem usuwania jednego lub więcej słoików, a następnie kompilować/uruchomić, aby sprawdzić, czy są one wymagane, czy nie.usunąć nieużywane słoiki z projektu

Odpowiedz

9

To, co zrobiłem w końcu
użyłem JBoss plotkarz (http://www.jboss.org/tattletale) w celu identyfikacji nieużywane słoików w czasie kompilacji (Poinformowano 17 słoików jako nieużywana).
Następnie dla każdego słoika z tej listy wykonałem wyszukiwanie w moim projekcie, aby sprawdzić, czy najwyższy poziom pakietu słoika został użyty w dowolnym miejscu (jest to próba sprawdzenia, czy jakakolwiek klasa należąca do tego słoika została załadowana za pomocą refleksji).
W ten sposób udało mi się wyeliminować 6 słoików z mojego projektu.
Ponieważ liczba niewykorzystanych słoików w czasie kompilacji była niewielka, podejście to było szybkie.

+0

Zasady opowieści tattle –

+0

fajne, dzięki za sugestię. Czy możesz podać mały przykład tego, jak go używasz? –

+0

Czy Tattletale może być używany poza JBOSS, na przykład z Tomcat? – user7294900

4

Jeśli istnieje lepsze rozwiązanie tego, chciałbym to usłyszeć.

Problemem jest to, że nawet jeśli słoik nie jest potrzebna do skompilować, może to być potrzebne do metę. I ta "potrzeba" może być przechodnia. EG: Słoik, którego używasz, wymaga słoika, którego nie używasz i tylko w czasie wykonywania. Podobnie jak charakter błędów runtime, ujawnią się one tylko podczas próby wykonania kodu. Najgorszy przypadek, który może wystąpić dopiero po uruchomieniu produkcji.

Najlepszym rozwiązaniem, jakie znam, jest dokładnie to, czego nie chcesz robić: "usunięcie jednego lub więcej słoików, a następnie skompilowanie/uruchomienie w celu przetestowania, czy są one wymagane, czy nie".

2

Usuń -> Test -> Usuń -> Test -> Usuń -> Mam nadzieję, że cieszyć :)

Zmień projekt Maven i wybierz słoik tylko ty chcesz use. Dla mnie jest to najłatwiejszy sposób.

1

Jak zauważył tieTYT w swojej odpowiedzi, wiele słoików jest potrzebnych tylko podczas kompilacji. (na przykład słoje implementacji jdbc)

Innym rozwiązaniem może być napisanie agenta Java i zebranie wszystkich nazw klas. Następnie możesz odwzorować te nazwy klas na jar i sprawdzić, czy nie są potrzebne żadne słoiki.

Przykładowy 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 ... o mrówce

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

Innym podejściem staraliśmy się okien została wykorzystując fakt, że słoiki zablokowane, gdy klasy są ładowane. Uruchom aplikację i spróbuj usunąć z obszaru wykonawczego. Jeśli był używany, usuwanie powinno zakończyć się niepowodzeniem. Nie jestem pewien, czy jest to bezpieczne - wiem, że nie działa na Linuksie itp. Pliki mogą być usunięte bez problemu.

+0

Dzięki za odpowiedź, spróbuję go następnym razem! – flowerpot