2012-01-26 31 views
11

Những gì tôi đang cố gắng làm là viết một số plugin Maven quét các lớp ứng dụng tìm kiếm việc thực hiện một giao diện cụ thể (nó có thể là các lớp với một số chú thích) và cơ sở trên kết quả tạo ra một số mã. Tôi đã triển khai thành công plugin đang chạy trong giai đoạn tạo nguồn và viết mã nguồn vào thư mục nguồn đã tạo.quét java classpath trong maven plugin

Vấn đề là với đường dẫn lớp quét cho các triển khai/lớp giao diện cụ thể với một số chú thích. Tôi đang sử dụng thư viện Reflections để quét lớp theo cách sau:

private Set<Class< ? extends MyInterface >> scan(final String packageName) { 
    final Reflections reflections = new Reflections(packageName); 
    return reflections.getSubTypesOf(MyInterface.class); 
} 

Thật không may, phương pháp này trả về tập rỗng. Khi tôi in classpath của tôi trong lớp mở rộng org.apache.maven.plugin.AbstractMojo (giống trong đó tôi đang sử dụng Reflections) tôi nhận được kết quả sau:

/home/pd5108/apache-maven-2.2.1/boot/classworlds- 1.1.jar

Các lớp tôi muốn tìm bằng Reflections tồn tại trong các JAR phụ thuộc cũng như trong mô-đun trong đó plugin được định cấu hình. Nhìn vào classpath được in ra, có vẻ như vào thời điểm này (phụ thuộc vào nguồn tạo ra) các phụ thuộc được định nghĩa trong maven, tất cả đều không có trên classpath - có lẽ chúng được thêm vào trong các phase tiếp theo. Điều đó có đúng không? Có cách tiếp cận nào khác mà tôi có thể sử dụng không?

Dưới đây là cách làm thế nào classpath được in ra:

URL[] urls = ((URLClassLoader)sysClassLoader).getURLs(); 

for(int i=0; i< urls.length; i++) { 
    System.out.println(urls[i].getFile()); 
} 

Trả lời

5

buộc MOJO lĩnh vực lớp:

/** 
    * The project currently being built. 
    * 
    * @parameter expression="${project}" 
    * @readonly 
    * @required 
    */ 
    private MavenProject project; 

    /** @parameter expression="${localRepository}" */ 
    protected ArtifactRepository m_localRepository; 

    /**@parameter default-value="${localRepository}" */ 
    private org.apache.maven.artifact.repository.ArtifactRepository 
     localRepository; 

    /** @parameter default-value="${project.remoteArtifactRepositories}" */ 
    private java.util.List remoteRepositories; 

    /** @component */ 
    private org.apache.maven.artifact.factory.ArtifactFactory artifactFactory; 

    /** @component */ 
    private org.apache.maven.artifact.resolver.ArtifactResolver resolver; 

Nghị quyết của tất cả các lọ phụ thuộc:

final List<Dependency> dependencies = project.getDependencies(); 

    for (Dependency d : dependencies) { 

     final Artifact artifact = 
      artifactFactory.createArtifactWithClassifier(d.getGroupId(), 
       d.getArtifactId(), d.getVersion(), d.getType(), 
       d.getClassifier()); 

     try { 
      resolver.resolve(artifact, remoteRepositories, 
        localRepository); 
     } catch (ArtifactResolutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ArtifactNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     File artifactFile = artifact.getFile(); 
     System.out.println(artifactFile.getAbsolutePath()); 
    } 

Và bây giờ chúng ta cần phải quét những lọ sử dụng phản chiếu API tìm kiếm các lớp học phù hợp. Tại thời điểm này tôi nghĩ rằng không có cách nào khác, kể từ khi tôi làm việc trong giai đoạnvà các giá trị tạo tác cho các giai đoạn tiếp theo không được tính toán.

-2

Có thể nhanh hơn/an toàn/dễ dàng hơn để chỉ cần có danh sách Plugin cấu hình các lớp mà bạn muốn tạo mã dựa trên. Sau đó, bạn chỉ cần thêm nó vào pom và bạn đã hoàn tất. Không cần phản ánh, và nó chắc chắn sẽ tăng tốc độ chạy plugin.

+0

Đó là tùy chọn tôi xem là phương sách cuối cùng ... Vì tôi có nhiều lớp triển khai giao diện này và tất cả chúng đều được xem xét trong quá trình tạo mã tôi muốn tránh nhập tất cả chúng 'tĩnh'. Ngoài ra, các lớp này thường được thêm/xóa. –

+0

Bạn luôn có thể có một kịch bản lệnh shell đã thực hiện một cái gì đó như grep tất cả các tệp java cho "triển khai X" và sau đó phân tích cú pháp các tên lớp và xây dựng một tệp thuộc tính của chúng. Sau đó, có plugin của bạn sử dụng tập tin bất động sản để biết những gì các lớp học để tạo thêm mã cho là tốt. Nếu bạn không phải là unix, bạn có thể mô phỏng grep trong java tôi cho rằng, nhưng nó sẽ chậm hơn nhiều. – Michael

1

Có các phụ thuộc giả tạo được xác định trong các phần phụ thuộc phần và plugin được xác định trong <plugin><dependencies>.

Phụ thuộc trình cắm thêm được thêm vào đường dẫn lớp trong khi tôi không chắc chắn về phụ thuộc giả tạo. Bạn có cố gắng thêm các phụ thuộc plugin của mình theo số <plugin><dependencies> không?

+0

Theo lời khuyên của bạn, tôi đã thêm một 'phụ thuộc plugin' và bây giờ nó không thể nhìn thấy dưới classpath in ra (lạ), nhưng thư viện Reflections phát hiện các lớp thực hiện MyInterface đúng cách! Có cách nào tôi có thể bao gồm phụ thuộc tạo tác trong phụ thuộc plugin? Tôi muốn tránh sao chép toàn bộ phần:/ –

+1

@PiotrekDe Có lẽ bạn có thể tạo một dự án jar với tất cả các phụ thuộc cần thiết mà bạn sẽ sử dụng làm phụ thuộc cho cả POM và plugin. Tôi không chắc chắn nó có giá trị nỗi đau mặc dù ... –

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