Ant compila, mas na hora de executar o class não roda

3 respostas
goathi

Pessoal,
Estou fazendo um trabalho usando o Commons Configuation da Jakarta e preciso de 3 jars dentro da minha pasta lib. Para não ter que adicionar esses jars no CLASSPATH, eu criei um build.xml para refernciá-los na hora de compilar.

Aqui está o conteúdo do build.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="teste" default="compile" basedir=".">

        <property name="web-inf" value="\${basedir}/WEB-INF" />
        <property name="src" value="\${web-inf}/src" />
        <property name="classes" value="\${web-inf}/classes" />
        <property name="lib" value="\${web-inf}/lib" />

        <path id="classpath">
                <pathelement location="${lib}/commons-configuration-1.5.jar"/>
                <pathelement location="${lib}/commons-collections-3.2.jar"/>
                <pathelement location="${lib}/commons-lang-2.4.jar"/>
        </path>

        <target name="compile">
                <javac srcdir="\${src}" destdir="\${classes}">
                        <classpath refid="classpath"/>
                </javac>
        </target>
</project>

E aqui o código java de exemplo:

import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;

public class Commons {

        public static void main( String args[] ) throws Exception {

                XMLConfiguration conf = new XMLConfiguration( "../config/conf.xml" );
                conf.setExpressionEngine( new XPathExpressionEngine() );
                conf.setReloadingStrategy( new FileChangedReloadingStrategy() );

                System.out.println( conf.getString( "prop[@id='AW00']/num[@id='399']/res" ) );

        }
}

Na hora de rodar o ant ele compila corretamente, ou seja, ele consegue achar os .jars. Só que depois de compilado, se eu tento executar o .class ele diz que não encontra o pacote “org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;”

Veja:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/configuration/tree/ExpressionEngine
Caused by: java.lang.ClassNotFoundException: org.apache.commons.configuration.tree.ExpressionEngine
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

Pois bem, agora vem a pergunta: como pode ele não reclamar do pacote não encontrado na hora de compilar e reclamar na hora de executar o arquivo compilado sendo que este erro não parece ser um erro em tempo de execução pois de fato o pacote existe e o arquivo conseguiu ser compilado.

Alguém poderia me ajudar?
Obrigado!

3 Respostas

kaique

Um momento, compilar e executar são dois momentos diferentes. Quando você escreeu aquelas coisas de classpath no seu ant, no tempo de compilação o compilador sabe onde encontrar essas classes para fazer as suas verificações. Quando você executa sua aplicação, essas outras lib’s devem estar no classpath da aplicação, pois senão a VM não vai saber onde encontrar as outras classes.
O que provavelmente deve estar acontecendo é que você não está colocando essas lib’s no classpath. Dá uma verificada nisso…

[]'s.

goathi

Kaique,
Obrigado por me responder!
O que eu não queria era ter que colocar todos as libs diretamente no CLASSPATH. Não gostaria de fazer isso toda vez que precisasse usar algum .jar. Aí vi que com o ant não preciso fazer isso para coseguir compilar.

Não existe uma forma de executar as classes sem especificar os jars no CLASSPATH?

Valeu!

kaique

Cara, sempre você vai ter que colocar as classes no classpath. Só assim a VM vai conseguir encontrar as classes que você está tendando executar.
Agora, esse processo pode ser feito de várias maneiras, por exemplo, as que eu me lembro que funcionam são:

1 -> Jogar essas lib’s no diretório default do Java. Assim, quando o compilador for carregar as classes padrão do Java, vai de quebra carregar as suas lib’s também. (Isso não é muito elegante e é pouco usado);

2 -> Alterar o classpath da aplicação no momento da execução da VM. Isso pode ser feito via prompt de comando passando o parâmetro -classpath;

3 -> Através de ClassLoader’s. Você pode chamar o ClassLoader default e adicionar as lib’s no classpath, ou então criar um ClassLoader específico para essa função. Existe um artigo aqui no GUJ explicando mais sobre ClassLoader;

Espero ter ajudado.
[]'s.

Criado 29 de março de 2008
Ultima resposta 29 de mar. de 2008
Respostas 3
Participantes 2