2015-08-20 41 views
9

Viene visualizzato un errore relativo al classpath nella fase di esecuzione. L'errore èjava.lang.NoClassDefFoundError ANT build

run: 
    [java] java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver 
    [java] at java.lang.Class.getDeclaredMethods0(Native Method) 
    [java] at java.lang.Class.privateGetDeclaredMethods(Unknown Source) 
    [java] at java.lang.Class.privateGetMethodRecursive(Unknown Source) 
    [java] at java.lang.Class.getMethod0(Unknown Source) 
    [java] at java.lang.Class.getMethod(Unknown Source) 
    [java] at sun.launcher.LauncherHelper.validateMainClass(Unknown Source) 
    [java] at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source) 
    [java] Caused by: java.lang.ClassNotFoundException: org.openqa.selenium.WebDriver 
    [java] at java.net.URLClassLoader.findClass(Unknown Source) 
    [java] at java.lang.ClassLoader.loadClass(Unknown Source) 
    [java] at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
    [java] at java.lang.ClassLoader.loadClass(Unknown Source) 
    [java] ... 7 more 
    [java] Error: A JNI error has occurred, please check your installation and try again 
    [java] Exception in thread "main" 
    [java] Java Result: 1 
BUILD SUCCESSFUL 
Total time: 1 second 

Questo è il codice di build xml che ho scritto. Mi riferisco alla cartella jacks di RunningPower e credo che la cartella corretta sia referenziata come sono in grado di compilare. La mia directory di base contiene anche un file .classpath e .project ma non è sicuro che siano importanti.

<?xml version="1.0" ?> 

<project name="SeleniumProjectDataDriven" basedir="." default="run"> 
    <target name="init"> 
     <property name="src.dir" value="src" /> 
     <property name="build.dir" value="build" /> 
     <property name="classes.dir" value="${build.dir}/class" /> 
     <property name="lib.dir" value="RunningPowerJars" /> 
    </target> 

    <target name="clean" depends="init"> 
     <delete dir="build"/> 
    </target> 

    <target name="compile" description="Compiles the code" depends="clean" > 
     <mkdir dir="${classes.dir}" /> 
     <javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false"> 
      <classpath> 
       <fileset dir="${lib.dir}"> 
        <include name="**/*.jar" /> 
       </fileset> 
      </classpath> 
     </javac> 
    </target> 

    <target name="jar" description="Packages the code into jar" depends="compile"> 
     <mkdir dir="build/jar"/> 
      <jar destfile="build/jar/RunningPower.jar" basedir="build/class"> 
       <manifest> 
        <attribute name="Main-Class" value="RunningPower"/> 
       </manifest> 
      </jar> 
    </target> 

    <target name="run" description="Run the jar file" depends="jar" > 
     <java jar="build/jar/RunningPower.jar" fork="true"/> 
    </target> 
</project> 

Nella mia cartella RunningPowerJars, essi contengono

junit-4.8.1.jar 
ojdbc6.jar 
poi-3.7-20101029.jar 
selenium-java-2.46.0.jar 
selenium-server-standalone-2.46.0.jar 
testng-6.1.1.jar 

Update (07:32 PST 8/21/2015)

<target name="run" description="Run the jar file" depends="jar" > 
    <java jar="build/jar/RunningPower.jar" fork="true"> 
     <classpath> 
      <fileset dir="${lib.dir}"> 
      <include name="**/*.jar" /> 
      </fileset> 
     </classpath> 
    </java> 
</target> 

ho modificato il codice, ma sono imbattuto in un altro errore .

BUILD FAILED 
C:\Users\dt208672\Perforce\depot\ebill\Automation\Selenium_eBill\RunningPower\build.xml:37: Problem: failed to create task or type classpath 
Cause: The name is undefined. 
Action: Check the spelling. 
Action: Check that any custom tasks/types have been declared. 
Action: Check that any <presetdef>/<macrodef> declarations have taken place. 

risposta

6

Il percorso di classe è necessario anche quando si esegue il file jar in modo che la JVM potrebbe trovare classi della libreria. Tuttavia, quando si utilizza l'attributo jar nell'attività java, "tutte le impostazioni del percorso di classe vengono ignorate" (vedere https://ant.apache.org/manual/Tasks/java.html). Il modo più semplice è quello di specificare la classe principale e aggiungere il vaso compilato insieme con i vasi della biblioteca si trovano nella directory RunningPowerJars:

<target name="run" description="Run the jar file" depends="jar" > 
    <java classname="RunningPower" fork="true"> 
     <classpath> 
      <pathelement location="build/jar/RunningPower.jar"/> 
      <fileset dir="${lib.dir}"> 
       <include name="**/*.jar" /> 
      </fileset> 
     </classpath> 
    </java> 
</target> 

Una nota non correlata è che si potrebbe utilizzare le proprietà definite nel init tutto il BuildFile. Ad esempio, nel target jar è possibile utilizzare ${classes.dir} anziché ripetere build/class.

Non ha ancora senso il motivo per cui la compilazione fallirebbe se l'elemento classpath viene aggiunto all'interno dell'attività java quando si utilizza l'attributo jar. Anche se viene ignorato, è strano che non riesca con l'errore "impossibile creare attività o tipo".

+1

@LinhSaysHi L'aggiornamento non è stato eseguito correttamente. Il 'classpath' dovrebbe essere _inside_ l'elemento' java'. – manouti

+0

L'ho risolto. Mi dispiace per quello! Tuttavia lo stesso errore si verifica ancora – LinhSaysHi

+1

@LinhSaysHi Ho aggiornato la risposta. 'classpath' viene in realtà ignorato quando si usa l'attributo' jar' nel task 'java'. Tuttavia, è strano che fallisca con quell'errore. – manouti

0

Considerare che quando si utilizza il parametro -jar utilizzando java.exe nella riga di comando, il parametro classpath viene ignorato, che si verifica anche con l'attività java nel form.

Quindi, quello che devi fare è fornire le librerie necessarie per il processo di avvio di quella formica e che sarà sufficiente.

Una volta ha detto che ... dove dovresti aggiungere quelle librerie allora? se si avvia da eclipse, è possibile aggiungerli in Window-> preferences in Ant-> Runtime-> Global Entries.

Se si sta utilizzando un C.I. server come jenkins potresti aggiungerli in molti modi, non posso dare una risposta diretta perché potrebbero essercene molti.

C'è anche un'alternativa. Puoi dichiarare la dipendenza dal .jar MANIFEST.MF e metterlo sotto/lib o qualsiasi cosa all'interno di quel jar.

Problemi correlati