2012-01-26 3 views
11

내가하려고하는 것은 특정 인터페이스의 구현을 찾고있는 애플리케이션 클래스를 스캔하는 Maven 플러그인을 작성하는 것이다 (일부 애노테이션을 가진 클래스 일 수도있다) 몇 가지 코드를 생성합니다. 나는 generate-sources 단계에서 실행중인 플러그인을 성공적으로 구현했고 generated-sources 디렉토리에 소스 코드를 작성했다.maven plugin에서 java 클래스 경로 검색하기

일부 주석이있는 특정 인터페이스 구현/클래스에 대한 클래스 경로 검색 문제가 있습니다. 나는 다음과 같은 방법으로 클래스를 검사 할 Reflections 라이브러리를 사용하고 있습니다 :

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

불행하게도,이 방법은 빈 집합을 반환합니다.

/home/pd5108/apache-maven-2.2.1/boot/classworlds- : 나는 클래스가 나는 다음과 같은 결과를 얻을 수 (이 안에 내가 Reflections을 사용하고 같은) org.apache.maven.plugin.AbstractMojo 확장에 내 클래스 경로를 인쇄 할 때 1.1.jar

Reflections를 사용하여 찾고자하는 클래스는 의존성 JAR과 플러그인이 구성된 모듈에 존재합니다. 클래스 패스를 살펴보면, 클래스 패스에서 사용할 수없는 maven에 정의 된 종속성이이 시점에서 생성됩니다. 아마도 다음 단계에 추가 될 것입니다. 그게 사실이야? 내가 사용할 수있는 다른 방법이 있습니까? 여기

이 클래스 경로를 인쇄하는 방법을 방법입니다 :

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

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

답변

5

필수 MOJO 클래스 필드 :

/** 
    * 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; 

모든 종속성 JAR 파일의 해상도 :

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()); 
    } 

그리고 지금 우리는 적절한 클래스를 찾고 반사 API를 사용하여 이러한 JAR 파일을 스캔해야합니다. generate-sources 단계에서 작업하고 다음 단계의 이슈 값이 아직 계산되지 않았으므로이 시점에서 나는 다른 방법이 없다고 생각합니다.

-2

이 빨리 될 수/안전/쉽게 그냥 플러그인 설정 목록 당신이 기반으로 코드를 생성 할 수업을합니다. 그런 다음 당신은 단지 폼에 그것을 추가 만하면됩니다. 리플렉션은 필요 없으며 확실히 플러그인 실행 속도를 높일 것입니다.

+0

내가 최후의 수단으로 생각하는 옵션입니다.이 인터페이스를 구현하는 클래스가 많아서 코드 생성시 모든 클래스가 '정적으로'입력하지 않도록하고 싶습니다. 또한 이러한 클래스는 자주 추가/제거됩니다. –

+0

"implements X"에 대한 grep all java 파일과 같은 기능을 수행하는 쉘 스크립트를 항상 가질 수 있으며 클래스 이름을 구문 분석하고 속성 파일을 빌드 할 수 있습니다. 그런 다음 플러그인이 해당 등록 정보 파일을 사용하여 추가 코드를 생성 할 클래스를 파악하십시오. 유닉스에 있지 않다면, 내가 생각하기에 자바에서 grep을 에뮬레이션 할 수는 있지만 훨씬 느릴 것이다. – Michael

1

<dependencies> 섹션에 정의 된 이슈 종속성이 있으며 <plugin><dependencies>에 정의 된 플러그인 종속성이 있습니다.

플러그인 종속성이 클래스 경로에 추가되는 동안 이슈 종속성에 대해 확신 할 수 없습니다. <plugin><dependencies> 아래에 플러그인 의존성을 추가하려고 했습니까?

+0

귀하의 조언에 따르면, 나는 '플러그인 의존성'을 추가했으며 클래스 패스 아래에서 보이지는 않지만 (이상한) Reflections 라이브러리는 MyInterface를 올바르게 구현하는 클래스를 감지합니다! 플러그인 종속성에 이슈 종속성을 포함시킬 수있는 방법이 있습니까? 나는 전체 섹션의 복사 - 붙여 넣기를 피하고 싶습니다./ –

+1

@PiotrekDe POM과 플러그인 모두에 대한 종속성으로 사용할 모든 필요한 종속성을 가진 jar 프로젝트를 만들 수 있습니다. 나는 그것이 고통의 가치가있다라고 확신하지 않는다. .. –

관련 문제