2015-01-29 1 views
2

우리는 Ant를 사용하여 제품 생성 워크 플로를 제어하고 대상의 수가 매우 광범위합니다. 우리는 다수의 build.xml 파일, 즉 다른 대상 (병렬로 실행되는 많은 대상)을 호출하는 대상을 사용합니다.Apache Ant에서 호출 (또는 부모) 대상 찾기

우리는 BuildEvents를 수신하고 모든 대상에 대한 시작 및 중지 시간을 Oracle 데이터베이스에 기록 할 수 있도록 Ant BuildListener를 확장하는 Java 클래스가 있습니다. 그러나 이제는 각 대상의 상위 대상을 파악할 수 있어야합니다.이 정보도 마찬가지로 기록되어야합니다. 나는이 그래서 만약 :

<target name="targetA"> 
    <parallel> 
     <antcall target="targetB"/> 
     <antcall target="targetC"/> 
    </parallel> 
    <antcall target="targetD"/> 

을 때때로 우리의 목표는 같은 build.xml 파일에서 대상에 여러 antcalls을, 때로는 우리는 대상을 지정하는 하위 디렉토리에있는 다른 build.xmls에 개미 통화를 할 수 .

필자는 targetA가 targetB의 부모임을 알 수있는 방법을 알고 싶습니다. 내 청취자의 BuildEvent 속성에서이 정보를 확인할 수 있다고 생각했습니다. 그러나 그것은 사용할 수없는 것 같습니다. 그래서 내가 targetB가 시작되었다는 것을 말해주는 BuildEvent를 받으면 BuildEvent는 TargetA에 대해 모른다.

누구나 이와 같은 시도를 성공 했습니까? 나는 청취자를 사용하려고 시도했지만 대상 계층을 결정할 수있는 후행 프로세스에 반대하지는 않습니다.

+0

프로그래밍 중이거나 프로그래밍 언어로 Ant를 사용하고 있습니까? –

+0

우리는 소프트웨어를 빌드하기 위해 개미를 사용하고 있으며, 제품 (제품)을 빌드하기위한 워크 플로우로 ETL 프로세스를 사용하고 있습니다. 그러나 소프트웨어 내의 일부 Java 클래스는 BuildListener와 같은 ant 클래스를 확장합니다. –

답변

1

나는 이것에 대해 완전히 확신하지는 않지만, 여러분이 이와 비슷한 것을 할 수 있다고 생각한다. (이것은 타겟이 병렬로 실행될 때, 개미가 사용하는 주 스레드와 다른 스레드에서 실행되고 다른 스레드에서 실행된다고 가정한다. 대상은 빌드 수신기와 동일한 스레드에서 실행됩니다.

import java.util.Stack; 

import org.apache.tools.ant.BuildEvent; 
import org.apache.tools.ant.BuildListener; 
import org.apache.tools.ant.Target; 


public abstract class MyBuildListener implements BuildListener { 

    private Thread mainThread = Thread.currentThread(); 

    private Stack<Target> callingTargets = new Stack<Target>(); 

    private ThreadLocal<Stack<Target>> callingTargetsPerThread = new ThreadLocal<Stack<Target>>(); 

    @Override 
    public void targetStarted(BuildEvent event) { 
     if(Thread.currentThread()==mainThread) { 
      printCallingStack(callingTargets); 
      callingTargets.push(event.getTarget()); 
     } else { 
      Stack<Target> callingTargetsForThread = callingTargetsPerThread.get(); 
      if(callingTargetsForThread==null) { 
       callingTargetsPerThread.set(callingTargetsForThread = new Stack<Target>()); 
      } 
      printCallingStack(callingTargetsForThread); 
      printCallingStack(callingTargets); 
      callingTargetsForThread.add(event.getTarget()); 
     } 
    } 

    @Override 
    public void targetFinished(BuildEvent event) { 
     if(Thread.currentThread()==mainThread) { 
      callingTargets.pop(); 
     } else { 
      Stack<Target> callingTargetsForThread = callingTargetsPerThread.get(); 
      callingTargetsForThread.pop(); 
      if (callingTargetsForThread.isEmpty()) { 
       callingTargetsPerThread.remove(); 
      } 
     } 
    } 

    private void printCallingStack(Stack<Target> stack) { 
     for(int i=stack.size();i>=0;i--) { 
      System.out.println(stack.get(i).getName()); 
     } 
    } 

} 
+0

감사합니다. 나는 당신의 가정에 대해 잘 모르겠지만, 나는 그것을 한 번 줄 것이다. –

+0

@JoeRoberts Ant 코드를 읽을 수있는 한, 제 가정은 용인 될 수 있습니다. Ant를 실행하는 것과 같은 스레드에서 BuildListener를 인스턴스화하면 내 가정이 정확하다고 생각합니다. 디버그 모드에서 이것을 실행하면 이것이 올바른지 빨리 알려줄 것입니다. 생성자와 이벤트 통지 메소드에서 현재 스레드의 이름을 출력 할 수도 있습니다. –

+0

감사! 나는 이것이 올바른 길이라고 생각한다. 그러나 중첩 된 병렬 처리가 발생할 때까지 작동합니다. <대상 이름 = "targetA"> \t \t <개미 DIR = "dirC"antfile \t \t \t <= "dirB"antfile = "fileB"대상 = "targetB"개미 DIR> : 이러한 유형의 시나리오 감안할 때 = "FILEC"대상 = "targetC"> \t dirB/fileB : <타겟 명 = "targetB"> ... targetB, targetX 및 targetY는 세 개의 개별 스레드에서 호출됩니다. 각 targetStarted와 함께 새 스택을 얻습니다. 나는 targetB가 부모 중 하나라는 것을 정말로 말할 수 없다. –