Jar file cannot find SWT library, but Eclipse can - java

I have an Ant build (see build.xml below) that compiles and runs as I expect within Eclipse.
When I run the build via the command-line (java -jar swtgui.jar), however, I receive the following error:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/widgets/Layout
at java.lang.Class.getDeclaredMethods0(Native Method)
...
etc
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project default="run" name="My Project ">
<target name="run" depends="createjar">
<java classname="com.company.program.project.MyMainClass">
<classpath path="staging">
<fileset dir="C:\COMPANY\Eclipse\3.6-64\plugins">
<include name="org.eclipse.swt.*.jar" />
</fileset>
</classpath>
</java>
</target>
<target name="createjar" depends="compile">
<jar destfile="./builds/jars/swtgui.jar" basedir="staging" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="com.company.program.project.MyMainClass" />
</manifest>
<fileset dir="C:\COMPANY\Eclipse\3.6-64\plugins\" includes="org.eclipse.swt.win32.win32.x86_64_3.6.0.v3650b.jar" />
</jar>
</target>
<target name="compile">
<javac includeantruntime="false" srcdir="./src" destdir="staging">
<classpath>
<fileset dir="C:\COMPANY\Eclipse\3.6-64\plugins">
<include name="org.eclipse.swt.*.jar" />
</fileset>
</classpath>
</javac>
</target>
<record name="./MyMainClass.log" loglevel="verbose" action="start"/>
The error doesn't make sense to me since I specify the same SWT library path for the compile target as I do for the createjar target.
If the SWT library is found for the compile target, why is it not found for the createjar target?

Related

Javac cannot find SWT library despite correct classpath

I have a Java project that uses SWT and compiles/runs perfectly.
When I try to compile via Ant, however, javac cannot find the SWT library despite the build.xml specifying the correct classpath.
The SWT library is located in C:\my_work\Eclipse\3.6-64\plugins\. As seen below (under the javac tags, this classpath is specified as such.
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project default="run" name="My Project">
<target name="run" depends="compile">
<java classname="com.company.program.project">
<classpath path="staging\" location="C:\my_work\Eclipse\3.6-64\plugins\"/>
</java>
</target>
<target name="compile">
<javac includeantruntime="false" srcdir="./src" destdir="staging">
<classpath path="C:\my_work\Eclipse\3.6-64\plugins\"></classpath>
</javac>
</target>
<jar destfile="./build/jars/swtgui.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="org.swtgui.MainGui" />
<attribute name="Class-Path" value="." />
</manifest>
<fileset dir="./bin/com/company/program/project" includes="**/*.class" />
<fileset dir="C:\my_work\Eclipse\3.6-64\plugins\" includes="org.eclipse.swt.win32.win32.x86_64_3.6.0.v3650b.jar" />
</jar>
<record name="./MyProject.log" loglevel="verbose" action="start"/>
The above gives me errors on import statements such as the following:
error: package org.eclipse.swt does not exist
import org.eclipse.swt.SWT;
^
Why does javac not find the SWT library when the classpath is correctly specified?
Also how can I find out where javac is looking? The logs -- even in verbose mode -- tell me nothing about where javac is trying to find these import statements.
SWT provides a separate Jar for standalone Java applications.
You can download the latest one from here - look at the 'SWT Binary and Source' section near the bottom of the page.
it seems <classpath path="C:\my_work\Eclipse\3.6-64\plugins\"></classpath> is not adding dependencies to compile classpath
this way works for me:
<target name="compile">
<javac includeantruntime="false" srcdir="./src" destdir="staging">
<classpath>
<fileset dir="C:\my_work\Eclipse\3.6-64\plugins">
<!-- <include name="**/*.jar" /> -->
<include name="org.eclipse.swt.*.jar" />
</fileset>
</classpath>
</javac>
</target>

Ant / External libraries

When I'm using external libraries (lucene) and running my java application through eclipse (run application) all works fine with the libs in the classpath.
But when I'm using Ant, i got this error here:
java.lang.ClassNotFoundException: org.apache.lucene.store.Directory
I guess this error shows up, cause of an incorrect classpath. Stange that no compilation error occurs, when ant compiles the code. This is my ant file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build">
<path id="classpath">
<pathelement location="bin"/>
<pathelement location="GUI_P/lucene-6.2.0/lucene-6.2.0/analysis/common/lucene-analyzers-common-6.2.0.jar"/>
<pathelement location="GUI_P/lucene-6.2.0/lucene-6.2.0/core/lucene-core-6.2.0.jar"/>
<pathelement location="GUI_P/lucene-6.2.0/lucene-6.2.0/grouping/lucene-grouping-6.2.0.jar"/>
<pathelement location="GUI_P/lucene-6.2.0/lucene-6.2.0/queryparser/lucene-queryparser-6.2.0.jar"/>
<pathelement location="GUI_P/lucene-6.2.0/lucene-6.2.0/queries/lucene-queries-6.2.0.jar"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.launch"/>
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target depends="init" name="build">
<javac debug="true" destdir="bin" includeantruntime="true">
<src path="src"/>
<classpath refid="classpath"/>
</javac>
</target>
<target name="jar" depends="build">
<mkdir dir="GUI_P"/>
<jar destfile="GUI_P/GUI_P.jar" basedir="bin">
<manifest>
<attribute name="Main-Class" value="gui.Gui"/>
</manifest>
</jar>
</target>
<target name="copySamples" depends="jar">
<copy todir="GUI_P/samples">
<fileset dir="src/gui/samples"/>
</copy>
</target>
</project>
Can you please help me here out?
It's not that strange, because ClassNotFoundException arises always when trying a dynamic instantiation (through Class.forName()). So it is possible that the same classpath produces a right compilation, but it is not complete for an execution: It lacks the dynamic dependencies.
In your case, you must add to the execution classpath the lucene-core library (at least).

Run ant script from command,error happened:Class not found: org.eclipse.jdt.core.JDTCompilerAdapter

In my java web project,there are code like <T> , in ant script, javac use JDK to compile java code, and it can't compile success.
Later,I know it must use eclipse JDT to compile.
And, in eclipse, ant script can run success.when run like this:
Right key click build.xml ---> Run ---> Run as ---> External Tools Configurations,click JRE,select "Run in the same JRE as the workspace".
After that, ant can run successful, in eclipse.
But, I want to write a .bat and .sh file to call ant script, to compile,war,deploy and start Tomcat.
So, ant should run from command. I tried more, error happend always:
Class not found: org.eclipse.jdt.core.JDTCompilerAdapter
PS, I have copy jar files about JDT in eclipse plugin to ant_home/lib directory.
Wish your response. Thanks in advance!
build.xml
`
<tstamp>
<format property="build.time" pattern="yyyy-MM-dd" />
</tstamp>
<path id="project.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${catalina.home}/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${ant.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<target name="clear">
<delete dir="${build.dir}" />
<delete dir="${dist.dir}" />
<delete file="${catalina.home}/webapps/${webapp.name}.war" />
<delete dir="${catalina.home}/webapps/${webapp.name}" />
</target>
<target name="init" depends="clear">
<mkdir dir="${build.dir}/classes" />
<mkdir dir="${dist.dir}" />
</target>
<target name="compile" depends="init">
<echo message="begin compile..." />
<javac srcdir="${src.dir}" destdir="${build.dir}/classes"
includeantruntime="false" nowarn="on"
source="1.6" target="1.6" deprecation="true" debug="true"
encoding="UTF-8" classpathref="project.classpath">
<compilerarg line="-Xlint:unchecked" />
</javac>
<copy todir="${build.dir}">
<fileset dir="${src.dir}">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.sql" />
</fileset>
<fileset dir="${config.dir}">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.sql" />
</fileset>
</copy>
<echo message="end compile..." />
</target>
<target name="war" depends="compile">
<echo message="begin war..." />
<war destfile="${dist.dir}/${webapp.name}.war" basedir="${webRoot.dir}"
webxml="${webRoot.dir}/WEB-INF/web.xml">
<lib dir="${lib.dir}" />
<classes dir="${build.dir}/classes" />
<fileset dir="${webRoot.dir}">
<include name="***.*" />
</fileset>
</war>
<echo message="end war..." />
</target>
<target name="deploy" depends="war">
<echo message="begin deploy..." />
<copy file="${dist.dir}/${webapp.name}.war" todir="${catalina.home}/webapps" />
<echo message="end deploy..." />
</target>
</project>
`
Don't use the ant from eclipse IDE for usage from command line.
Download ant separately and extract it somewhere like - C:\apache\ant - for windows, and put its bin directory in your PATH. It'll come with some jars that will need to be added to your CLASSPATH too.
For Mac OSX 'sudo port install ant" takes care of everything.
Download ecj*.jar from Eclipse and put in under ANT_HOME/lib.
Make sure that ANT_HOME is set under the shell environment or you should set the ecj*.jar in the CLASSPATH on the shell. (Otherwise, a Class not found: org.eclipse.jdt.core.JDTCompilerAdapter might be still thrown.)
For the record, I am also getting this error randomly (works more often than not) when using the <javac> task with that compiler adapter in a <parallel> context, i.e. in multi-threaded situation.
It looks as if the compiler adapter jar is temporarily locked and can't be accessed by the thread classloader or something. I don't have a workaround for it yet, short of removing the <parallel> execution.

Groovy unable to resolve java class

i got a problem by executing groovy from an ant file.
In Eclipse with a launcher, everything works fine but wehn i run the ant file i got the following output:
Main.groovy: 71: unable to resolve class InitializeDatabase
[groovyc] # line 71, column 40. [groovyc] java.lang.Object
javaClassInstance = new InitializeDatabase()
[groovyc]
[groovyc] 1 error
InitializeDatabase is a java class in the same package..
public class InitializeDatabase {
public void test() {
System.out.println("Hello Groovy");
}
}
I guess the problem is located at the ant file:
<project name="tp" basedir="." default="dbsetup">
<target name="dbsetup">
<taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc">
<classpath>
<fileset dir="../files/lib/default" includes="*.jar" />
</classpath>
</taskdef>
<delete dir="bin" />
<mkdir dir="bin" />
<groovyc srcdir="src" destdir="bin" />
<java classname="groovy.ui.GroovyMain" dir="../.." fork="true" failonerror="true">
<classpath>
<fileset dir="../files/lib/default" includes="*.jar"/>
<pathelement location="bin"/>
</classpath>
<arg line="build/scripts/src/build/Main.groovy" />
</java>
</target>
</project>
Can someone help me please?
You need to include the javac task inside your groovyc one. Change:
<groovyc srcdir="src" destdir="bin" />
to
<groovyc srcdir="src" destdir="build">
<javac/>
</groovyc>
And it should work fine. As it says here:
Joint compilation means that the Groovy compilation will parse the
Groovy source files, create stubs for all of them, invoke the Java
compiler to compile the stubs along with Java sources, and then
continue compilation in the normal Groovy compiler way. This allows
mixing of Java and Groovy files without constraint.
...
The right way of working is, of course, to use a nested tag and all
the attributes and further nested tags as required.
Here is the final file which works great.
Thanks to tim_yates!
<target name="dbsetup">
<taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc">
<classpath>
<fileset dir="../files/lib/default" includes="*.jar" />
</classpath>
</taskdef>
<delete dir="bin" />
<mkdir dir="bin" />
<groovyc srcdir="src" destdir="bin">
<javac source="1.6" target="1.6" debug="on" />
</groovyc>
<java classname="groovy.ui.GroovyMain" dir="../.." fork="true" failonerror="true">
<classpath>
<fileset dir="../files/lib/default" includes="*.jar"/>
<pathelement location="bin"/>
</classpath>
<arg line="build/scripts/src/build/access/AccessDbSetup.groovy" />
</java>
</target>

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Layout

I'm trying to build an application using ant. Everything appears to be fine when I build but I continually get the above error for what I've tried so far.
java -jar dist/pmml_export.jar
java -cp ".:log4j-1.2.16.jar" -jar dist/pmml_export.jar
java -cp log4j-1.2.16.jar -jar dist/pmml_export.jar
I doubled checked to see if Layout was in the jar I'm referencing and it is there. I'm fairly new to both ant and log4j so I could be making an obvious mistake but I'm just not seeing it. Here is my build.xml.
<?xml version="1.0"?>
<project name="pmml_export" default="archive">
<target name="init">
<mkdir dir="build/classes" />
<mkdir dir="dist" />
</target>
<path id="compile.classpath">
<fileset dir="build/classes" includes="*.class" />
</path>
<property name="ant.dir" value="apache-log4j-1.2.16"/>
<path id="classpath">
<fileset dir="${ant.dir}" includes="**/*.jar"/>
</path>
<target name="exceptions" depends="init">
<javac srcdir="src/exceptions" destdir="build/classes" classpathref="compile.classpath"/>
<echo> Exceptions compiled! </echo>
</target>
<target name="symbol-table" depends="exceptions" >
<javac srcdir="src/translator/symbol_table" destdir="build/classes" classpathref="compile.classpath"/>
<echo> Symbol table compiled! </echo>
</target>
<target name="parser" depends="symbol-table" >
<javac srcdir="src/translator/parser" destdir="build/classes" classpathref="compile.classpath"/>
<echo> Parser compiled! </echo>
</target>
<target name="lexer" depends="parser" >
<javac srcdir="src/translator/lexer" destdir="build/classes" classpathref="compile.classpath"/>
<echo> Lexer compiled! </echo>
</target>
<target name="translator" depends="lexer" >
<javac srcdir="src/translator" destdir="build/classes" classpathref="compile.classpath"/>
<echo> Translator compiled! </echo>
</target>
<target name="exporter" depends="translator" >
<javac srcdir="src/pmml_export" destdir="build/classes" classpathref="compile.classpath" />
<echo> Exporter compiled! </echo>
</target>
<target name="archive" depends="exporter" >
<property name="manifest.mf" location="dist/manifest.txt" />
<manifest file="${manifest.mf}" >
<attribute name="Main-Class" value="pmml_export.PMML_Export"/>
</manifest>
<jar destfile="dist/pmml_export.jar" manifest="${manifest.mf}"
basedir="build/classes" />
</target>
<target name="run" depends="archive">
<java jar="dist/pmml_exporter.jar" fork="true">
<classpath>
<path refid="classpath"/>
<path location="dist/pmml_exporter.jar"/>
</classpath>
</java>
</target>
</project>
When you use the -jar option, the -cp and -classpath options are ignored. The proper way to embed the classpath with the -jar option is to set a Class-Path directive in the jar's MANIFEST.MF file.

Categories