Clase no encontrada con Ant, Ivy y JUnit – error en build.xml?

Estoy tratando de obtener un proyecto de prueba simple (?) Que trabaje con Ant, Ivy y JUnit. La idea básica es que Ivy descargará junit.jar y luego Ant lo usará.

Tenga en cuenta que junit jar está en classpath porque de lo contrario (sin el elemento classpath en la tarea junit) veo que ” for debe incluir junit.jar si no está en el propio classpath de Ant”. Además, la clase dada a continuación (junit.framework.TestListener) está en junit-4.8.2.jar.

Sin embargo, cuando pruebo la ant test en lo siguiente veo:

 test: BUILD FAILED /home/andrew/project/guice/hg/build.xml:33: java.lang.NoClassDefFoundError: junit/framework/TestListener at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:791) ... at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) Caused by: java.lang.ClassNotFoundException: junit.framework.TestListener at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ... 

¿Entonces supongo que algo está mal con mi build.xml? ¿Qué?

Aquí está el build.xml:

   simple example build file                                        

y la estructura de directorio existente después de la comstackción:

 . ├── build │  └── com │  └── isti │  └── example │  ├── AppendToList.class │  ├── DumpToStdout.class │  ├── LimitedCounter.class │  ├── MessageSink.class │  ├── MessageSource.class │  └── SinkToSourceTest.class ├── build.xml ├── dist │  └── lib │  └── example-20130412.jar ├── ivy.xml ├── lib │  ├── junit-4.8.2.jar │  ├── junit-4.8.2-javadoc.jar │  └── junit-4.8.2-sources.jar ├── README.md └── src ├── main │  └── java │  └── com │  └── isti │  └── example │  ├── AppendToList.java │  ├── DumpToStdout.java │  ├── LimitedCounter.java │  ├── MessageSink.java │  └── MessageSource.java └── test └── java └── com └── isti └── example └── SinkToSourceTest.java 

Actualización Incidentalmente, la ant -lib lib test (explícitamente dando el directorio lib) funciona. Y hay muchas descripciones confusas del manejo de esto en resultados de búsqueda web aleatorios, pero mi impresión es que el enfoque anterior es consistente con los últimos documentos (estoy usando ant 1.9) – ver el punto 5. Así que estoy pensando que esto puede ser un error ; error .

Ejemplo

Proyecto contiene los siguientes archivos:

 ├── build.xml ├── ivy.xml └── src ├── main │  ├── java │  │  └── org │  │  └── demo │  │  └── App.java │  └── resources │  └── log4j.properties └── test └── java └── org └── demo └── AppTest.java 

La comstackción se ejecuta de la siguiente manera:

 $ ant Buildfile: /home/mark/Files/Dev/ivy/demo/build.xml resolve: [ivy:resolve] :: Apache Ivy 2.3.0 - 20130110142753 :: http://ant.apache.org/ivy/ :: [ivy:resolve] :: loading settings :: url = jar:file:/home/mark/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml [ivy:resolve] :: resolving dependencies :: com.myspotontheweb#demo;working@mark-Lemur-Ultra [ivy:resolve] confs: [compile, runtime, test] [ivy:resolve] found org.slf4j#slf4j-api;1.7.5 in public [ivy:resolve] found org.slf4j#slf4j-log4j12;1.7.5 in public [ivy:resolve] found log4j#log4j;1.2.17 in public [ivy:resolve] found junit#junit;4.11 in public [ivy:resolve] found org.hamcrest#hamcrest-core;1.3 in public [ivy:resolve] :: resolution report :: resolve 347ms :: artifacts dl 14ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | compile | 1 | 0 | 0 | 0 || 1 | 0 | | runtime | 3 | 0 | 0 | 0 || 3 | 0 | | test | 5 | 0 | 0 | 0 || 5 | 0 | --------------------------------------------------------------------- [ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-compile.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-compile.html [ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-runtime.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-runtime.html [ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-test.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-test.html resources: [copy] Copying 1 file to /home/mark/Files/Dev/ivy/demo/build/classes compile: [javac] Compiling 1 source file to /home/mark/Files/Dev/ivy/demo/build/classes compile-tests: [mkdir] Created dir: /home/mark/Files/Dev/ivy/demo/build/test-classes [javac] Compiling 1 source file to /home/mark/Files/Dev/ivy/demo/build/test-classes test: [mkdir] Created dir: /home/mark/Files/Dev/ivy/demo/build/test-reports [junit] Running org.demo.AppTest [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.085 sec build: [ivy:retrieve] :: retrieving :: com.myspotontheweb#demo [ivy:retrieve] confs: [runtime] [ivy:retrieve] 3 artifacts copied, 0 already retrieved (512kB/16ms) [jar] Building jar: /home/mark/Files/Dev/ivy/demo/build/dist/demo.jar BUILD SUCCESSFUL Total time: 4 seconds 

ivy.xml

Una característica muy poderosa de la hiedra es la configuración . Esto le permite agrupar dependencias.

                 

Notas:

  • Las configuraciones usan la función “extends” para emular los scopes Maven “comstackr”, “runtime” y “test” Maven.
  • Tenga en cuenta el atributo especial “conf” en cada dependencia. Este es el mapeo de local a remoto. Para obtener más detalles sobre cómo los módulos Maven remotos son gestionados por hiedra, consulte: ¿Cómo se mapean los ámbitos Maven en hiedra?

build.xml

Las configuraciones de Ivy se pueden aprovechar mediante tareas como cachepath (para crear una ruta ANT) y recuperar (copiar archivos en su comstackción). También recomiendo usar el objective del informe para que pueda ver qué jarras aparecen en cada configuración (Útil para administrar dependencias transitivas)

                                                                                          

Nota:

  • El objective condicional “install-ivy” instalará ivy automáticamente. Simplemente vuelva a ejecutar la comstackción, solo debe hacerse una vez.

App.java

Hola ejemplo de registro mundial.

 package org.demo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Hello world! * */ public class App { static final Logger log = LoggerFactory.getLogger(App.class); public static void main( String[] args ) { App a = new App(); a.speak("hello world"); } public void speak(String message) { log.info(message); } } 

AppTest.java

Este es un viejo ejemplo de mis archivos. No usar las aserciones de Junit.

 ackage org.demo; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Unit test for simple App. */ public class AppTest extends TestCase { /** * Create the test case * * @param testName name of the test case */ public AppTest( String testName ) { super( testName ); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite( AppTest.class ); } /** * Rigourous Test :-) */ public void testApp() { assertTrue( true ); } } 

log4j.properties

 # Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n