2010-10-20 5 views
5

Ho scritto due diverse attività Ant personalizzate. Stanno provando a condividere i dati attraverso un membro statico in una classe base. Questo non funziona per me.Come posso condividere i dati tra attività Ant personalizzate?

Suppongo di utilizzare correttamente i membri statici in Java. Penso che questo sia un problema di caricamento dinamico con la VM Java. Tuttavia, sono un neofita relativamente con Java.

Poiché le attività personalizzate di Ant vengono mappate in fase di runtime mediante l'attività taskdef, il motore di generazione Ant deve caricare dinamicamente questo codice tramite java.lang.reflect.Constructor.newInstance().

C'è un trucco per farlo funzionare?

Nota: questo funziona perfettamente nel codice Java "normale" ... è il caricamento dinamico di Ant che è il problema.

classi Esempio:

 
import org.apache.tools.ant.Task; 

public class AntCustomTaskShared extends Task { 
    private static Integer _static_bigdata = null; 
    public Integer get_bigdata() { 
     if (_static_bigdata == null) { 
      log("alloc"); // from ant Task class 
      _static_bigdata = new Integer(0); 
     } 
     return _static_bigdata; 
    } 
} 
 
import org.apache.tools.ant.BuildException; 

public class AntCustomTask1 extends AntCustomTaskShared { 
    public void execute() throws BuildException { 
     Integer big_data = get_bigdata(); // "alloc" is printed 
     // do stuff with big_data 
     log("I'm doing big stuff"); 
    } 
} 
 
import org.apache.tools.ant.BuildException; 

public class AntCustomTask2 extends AntCustomTaskShared { 
    public void execute() throws BuildException { 
     Integer big_data = get_bigdata(); // "alloc" is printed (again) 
     // do stuff with big_data 
     log("I'm doing big stuff again"); 
    } 
} 

Esempio Ant build.xml:

 
<?xml version="1.0" encoding="UTF-8"?> 
<project name="MyTask" basedir="." default="init"> 
    <target name="init" 
      description="test the custom task" 
    > 
     <taskdef name="CustomTask1" 
       classname="AntCustomTask1" 
       classpath="C:\my_custom_ant_task_class_files" 
     /> 
     <taskdef name="CustomTask2" 
       classname="AntCustomTask2" 
       classpath="C:\my_custom_ant_task_class_files" 
     /> 
     <CustomTask1/> 
     <CustomTask2/> 
    </target> 
</project> 

fare tutto quanto sopra e vedrete "alloc" registrati due volte. Non riesco a ottenere questi due compiti personalizzati per condividere i "big data".

Sono in esecuzione formica 1.8.1 su Windows con questi due env vars:

  • JAVA_HOME = C: \ Program Files \ Java \ jdk1.6.0_21
  • CLASSPATH = (vuoto)

Suggerimento: se si desidera entrare in questo compito personalizzato da una (1,8) processo di Formica, impostare i punti di interruzione qui:

  • org.apache.tools.ant.launch.Launcher.main()
  • org.apache.tools.ant.UnknownElement.execute()
+0

potrebbe postare un semplice accumulo che illustra questo? Ho provato questo a livello locale e sembra funzionare per me - nessun secondo alloc è stampato. –

+0

Uso della build di esempio Non ottengo due chiamate al costruttore BigData. Adesso vedete due allocazioni: una da println e una dal logger. Ho tutte le classi in una directory. –

risposta

1

La soluzione è semplice, ma scarsamente (o non?) Documentata sul sito Web di Ant. (Effettuerò una patch ai documenti Ant per correggere questa situazione!)

Avevo bisogno di usare l'attributo loaderref sui nodi taskdef. Il token viene utilizzato per fare riferimento a ClassLoader (e condividerlo). Dopo, i membri statici vengono condivisi correttamente tra le attività personalizzate.

Corretto Ant build.xml:

 
<?xml version="1.0" encoding="UTF-8"?> 
<project name="MyTask" basedir="." default="init"> 
    <target name="init" 
      description="test the custom task" 
    > 
     <taskdef name="CustomTask1" 
       classname="AntCustomTask1" 
       classpath="C:\my_custom_ant_task_class_files" 
       loaderref="my_shared_class_loader" 
     /> 
     <taskdef name="CustomTask2" 
       classname="AntCustomTask2" 
       classpath="C:\my_custom_ant_task_class_files" 
       loaderref="my_shared_class_loader" 
     /> 
     <CustomTask1/> 
     <CustomTask2/> 
    </target> 
</project> 
+0

Ancora non vedo la descrizione di questo uso nella documentazione di Ant. Hai inviato una patch alla fine? – gkb0986

0

Questo è meno elegante, ma si potrebbe provare la condivisione delle informazioni attraverso i System.setProperty e System.getProperty chiamate. Il caricamento della classe ANT è decisamente diverso da una normale applicazione Java.