2013-09-30 24 views
7


Cách dễ nhất (công cụ?) Để loại bỏ các lọ không sử dụng khỏi dự án java (kiến) của tôi là gì. Dự án của chúng tôi đã trở nên thực sự rất lớn và chúng tôi muốn làm sạch. Có một số lọ được thêm vào classpath, nhưng không phải tất cả được sử dụng để biên dịch/chạy. Có cách nào để xác định các lọ không cần thiết bằng cách chạy một số tiện ích từ dòng lệnh?
Lưu ý: chúng tôi không muốn thực hiện theo quy trình tẻ nhạt của việc xóa một hoặc nhiều lọ, sau đó biên dịch/chạy để kiểm tra xem chúng có cần thiết hay không.loại bỏ các lọ không sử dụng khỏi dự án

Trả lời

9

Đây là những gì tôi đã làm cuối cùng
Tôi đã sử dụng JBOSS TattleTale (http://www.jboss.org/tattletale) để xác định các bình chưa sử dụng tại thời gian biên dịch (Báo cáo 17 bình chưa sử dụng).
Sau đó, đối với mỗi lọ trong danh sách đó, tôi đã tìm kiếm chuỗi trên dự án của tôi để tìm xem mức gói cao nhất của bình đã được sử dụng ở bất kỳ đâu (đây là một nỗ lực để xem liệu bất kỳ lớp nào thuộc jar này đã được nạp bằng cách sử dụng sự phản chiếu hay không).
Bằng cách này tôi đã có thể loại bỏ thành công 6 lọ từ dự án của tôi.
Vì số lượng lọ không sử dụng tại thời gian biên dịch nhỏ, cách tiếp cận này nhanh chóng.

+0

quy tắc tattle câu chuyện –

+0

mát mẻ, cảm ơn đề xuất. Bạn có thể đưa ra một ví dụ nhỏ về cách bạn sử dụng nó? –

+0

Tattletale có thể được sử dụng ngoài JBOSS, ví dụ Tomcat không? – user7294900

4

Nếu có giải pháp tốt hơn cho điều này, tôi rất muốn nghe nó.

Vấn đề là ngay cả khi bình không cần thiết để biên dịch, bạn có thể cần đến chạy. Và "nhu cầu" này có thể được chuyển đổi. EG: Một cái lọ bạn sử dụng cần một cái lọ bạn không sử dụng và chỉ khi chạy. Vì bản chất của các lỗi thời gian chạy, chúng sẽ chỉ tiết lộ khi bạn cố gắng thực thi mã. Trường hợp xấu nhất, có thể không xảy ra cho đến khi bạn đang chạy trong sản xuất.

Giải pháp tốt nhất mà tôi biết là chính xác những gì bạn không muốn làm: "loại bỏ một hoặc nhiều lọ, sau đó biên dịch/chạy để kiểm tra xem chúng có được yêu cầu hay không".

2

Remove -> Test -> Remove -> Test -> Remove -> Hy vọng bạn tận hưởng Thay đổi dự án :)

để maven và chỉ chọn jar bạn muốn sử dụng. Đối với tôi, đây là cách dễ nhất.

1

Như đã lưu ý bởi tieTYT trong câu trả lời của mình, nhiều lọ chỉ cần thiết khi biên dịch. (ví dụ các lọ thực hiện jdbc)

Một cách tiếp cận khác có thể là viết một tác nhân java và thu thập tất cả các tên lớp. Sau đó, bạn có thể ánh xạ những tên này thành jar và xem có cần thiết không có bất kỳ lọ nào không.

đại lý Mẫu

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

Một cách tiếp cận chúng tôi cố gắng trong cửa sổ đã sử dụng thực tế là các lọ bị khóa khi các lớp được nạp. Chạy ứng dụng và cố gắng xóa khỏi vùng thời gian chạy. Nếu nó được sử dụng, xóa sẽ thất bại. Không chắc chắn như thế nào an toàn này là-Tôi biết rằng nó không hoạt động trên linux vv, các tập tin có thể bị xóa mà không có vấn đề.

+0

Cảm ơn câu trả lời của bạn, sẽ dùng thử lần sau! – flowerpot

Các vấn đề liên quan