I am not sure If I am asking a very simple question but I have a project in which the developer has used "XSD" files to create java source codes. The input to the project is an XML message which will be parsed into java object.
The project is working fine if I export the class files into a jar file (using eclipse options to export class files into jar files).
But if I use "ant" script to compile and create a jar file, I always get "JAXBException". After Checking I found that the main java file is compiled into 2 class files by ant script, whereas when I use eclipse to compile there is only one class file.
For example -
Main Java file - MpgProcessor.java
Compile using eclipse - MpgProcessor.class
Compile using ant - MpgProcessor.class and MpgProcessor$1.class.
I am using following command in ant to compile the java files -
<target name="compile" depends="clean-build-files" >
<echo message="STEP 2 = COMPILING JAVA FILES " />
<mkdir dir="${classDir}" description="Ensure launch directory created" />
<javac srcdir="${src.dir}" destdir="${classDir}" classpathref="build.classpath" debug="on" compiler="javac1.6"/>
<javac srcdir="${src.generated}" destdir="${classDir}" classpathref="build.classpath" debug="on" compiler="javac1.6" verbose="off"/>
</target>
Can anyone please help?
Related
We are shifting from jdk 1.8 to jdk13. In our build.xml we have
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javah class="com.zimbra.znative.IO" outputfile="${build.dir}/IO.h" classpathref="build.class.path"/>
</target>
But java10+ is not supporting javah anymore so I found we can achieve this with javac "nativeheaderdir" here - https://ant.apache.org/manual/Tasks/javac.html#nativeheaderdir
So I tried to convert above javah task to javac as below
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" nativeHeaderDir="${build.dir}" classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java" />
</target>
Now the missing javah error gone, but I don't see IO.h file generated in my build directory.
Can anyone help me, how to do this? Your help is really appreciated, thank you.
Note: directory src/java/com/zimbra/znative have around 5-6 .java files. I mentioned an example for 1 file only.
I can't see an obvious way to persuade the javac task to do this. nativeHeaderDir= generates the headers, but won't concatenate as you have found.
A post-javac workaround might look like this - combine the per-class headers into a single file using the Ant <concat> task:
<concat destfile="IO.h">
<header>/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
</header>
<concat destfile="IO.h">
<fileset dir="${build.dir}" includes="*.h" />
<filterchain>
<linecontainsregexp negate="true">
<regexp pattern="(#include .jni.h.)|(DO NOT EDIT THIS FILE - it is machine generated)" />
</linecontainsregexp>
</filterchain>
</concat>
</concat>
The basic idea is simple: find all the header files generated by javac, concatenate them into one header with the name required. Optionally, along the way, strip out the repeated #include and comment lines. The result should look the same as a JDK 8 javah-produced header.
With the below changes, I am able to create header files. But the generated file name is "com_zimbra_znative_IO.h". It should be "IO.h"
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" destdir="${build.dir}" nativeHeaderDir="${build.dir}" classpathref="build.class.path"
includes="IO.java"
excludes="Process.java,ProcessorUsage.java,ResourceUsage.java,Util.java,ProxyInfo.java" />
</target>
Generating header files using javac task from ant should be along with your generated class file. So if the corresponding class file already available and no change in the source file (other words your compiled class modification time is higher than the java source file) then the javac ant task won't do any action on that class file including native header file generation.
You have to perform few check,
Is your srcdir attribute pointing to the right directory which starts your packages. (ex. your class name is com.zimbra.znative.MyClass and the file path is src/java/com/zimbra/znative/MyClass.java then your srcdir should be point to src/java.
Provide destdir where your compiled class files will be generated, otherwise it will generate inside your srcdir.
Normally includes not required if you want to generate all header files which all the class having native method in your srcdir
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java" nativeHeaderDir="${build.dir}" destdir="${build.classes}"
classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java" />
</target>
Before running the ant make sure the IO.class file not exist or the source .java file has recent changes than the existing class file. then see it will generate the class file and header files. Header files should be inside ${build.dir}
how to remove java System.out.println from ant script?
(when we compile the code from ant we should remove the existing java class system.out.println & compiled classes should not have the Sys.out.println)
In build.xml file, preparation phase, before the mkdir commands,
provide:
<javac srcdir="exe" includes="SysOutRemove.java"/>
<java fork="true" classname="SysOutRemove" dir="exe" failonerror="true"/>
where SysOutRemove.java is in the exe package of your project.
SysOutRemove.java should iterate through the list of directories and files in them, store the contents of each file to a reader or something, find sysout statements and replace.
We can use this in the ant file.
<replaceregexp match="System.out.println(.*);" replace="" flags="g" byline="true">
<fileset dir="${src.dir}" includes="**/*.java"/>
</replaceregexp>
I would like to run the ant build-script without installing Java and setting any environment variable like path, JAVA_HOME & ANT_HOME to environment variable.
I have copied already installed folders of Jdk-1.7u17, Jre-1.7u17 and apache-ant-1.9.0 from one machine to another machine into C:\buildscript_required_files_v2 folder.
Now i have a window batch file that gets into the path where build.xml resides and run ant
cd VersionBuild
C:\buildscript_required_files_v2\apache-ant-1.9.0\bin\ant
build.xml complies the Java class and creates a Jar file.
<project name="VersionBuild" default="clean" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
</target>
<target name="CompilingBuildversion" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<C:\buildscript_required_files_v2\java\jdk64\bin\javac.exe srcdir="." destdir="."/>
</target>
<target name="Creating jar" depends="CompilingBuildversion">
<jar jarfile="VersionBuild.jar" basedir="."/>
</target>
<target name="clean" depends="Creating jar">
</target>
</project>
when I am running that bach file, I am getting the following exception -
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\li
b\tools.jar
Can I run ant build-script without installing Java and setting any environment variable? Can i specify JAVA_HOME for ant locally into the build.xml so ant can take refrence from C:\buildscript_required_files_v2 folder?
You problem is not concerned with *_HOME variables, but I first answer you question.
Yes you can.
Just configure your PATH variable to (1) dir where java.exe resides (2) where ant.bat resides.
In case when *_HOME defined the path can be written:
PATH=...;%JAVA_HOME%\bin;%ANT_HOME%
Since you have no such variables you need declare:
PATH=...;C:\Program Files\Java\bin;c:\ant\bin
But in real you problem that you try use JRE while ant needs JDK. Just download from oracle site. tools.jar is part of JDK but not JRE.
UPDATE:
You can write you own bat file that lets Windows know where to locate .exe and .bat files. Just create in notepad text file named my-ant.bat And place following there:
set JAVA_HOME=C:\buildscript_required_files_v2\java\jdk64
set PATH=%PATH%;%JAVA_HOME%\bin;C:\buildscript_required_files_v2\apache-ant-1.9.0\bin
rem ** Now we invoke ant **
ant
Obviously you would like manipulate with command line arguments. That is why instead of last ant line use following:
set my_ant_start=
:setupArgs
if ""%1""=="""" goto doneStart
set my_ant_start=%my_ant_start% %1
shift
goto setupArgs
:doneStart
rem ** Now we invoke ant **
ant %my_ant_start%
This question already has answers here:
javac option to compile all java files under a given directory recursively
(10 answers)
Closed 9 years ago.
How to compile all java files in all subfolders on Unix, using javac?
On Windows...
Create a batch file:
for /r %%a in (.) do (javac %%a\*.java)
...then execute it in the top-level source folder.
On Linux...
javac $(find ./rootdir/* | grep .java)
Both answers taken from this thread...
http://forums.oracle.com/forums/thread.jspa?threadID=1518437&tstart=15
But as others suggested, a build tool would probably prove helpful.
Use a build tool such as Ant or Maven. Both lets you manage dependencies in a much better way than can be accomplished using e.g. the find UNIX tool. Both And and Maven also lets you define custom tasks to be performed in addition to compilation. Maven furthermore comes with conventions for managing external dependencies in remote repositories, as well as conventions for running unit tests and features that support continuous integration.
Even if you just need to compile your source files once in a while, you'll probably find that setting up a simple Ant build.xml file can be a big time saver in the end.
Finally, most of the popular IDE and code editor applications has some kind of integration with Ant build scripts, so you can run all the Ant tasks from within the editor. NetBeans, Eclipse, IDEA and more also has built-in support for Maven.
Read this first, if you're new to Ant. Below is the example build file from the link:
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
Once you're familiar with Ant, you'll find it easier to move to Maven.
I don't know if it is the best way, but this should work :
find . -name "*.java" | xargs javac
Use Ant to write a script to compile as many source folders as you want.
Use Maven (as a more modern alternative to Ant).
Use an IDE, like Eclipse (all IDEs I know will happily compile multiple source folders for you)
Another (less flexible) way, if you know how much folder levels there are:
javac *.java */*.java */*/*.java */*/*/*.java */*/*/*/*.java ...
Depending on your shell, you may have to set it to expanding non-matching patterns to nothing, in bash with shopt -s nullglob. For example, I'm using the following shell function to find text in my java files:
function jgrep ()
{
(
shopt -s nullglob
egrep --color=ALWAYS -n "$#" *.tex *.java */*.java */*/*.java */*/*/*.java */*/*/*/*.java */*/*/*/*/*.java
)
}
jgrep String
But really, use an build tool, as the others said.
My Java application has got a package structure similar to this:
src/com/name/app
src/com/name/app/do
src/com/name/utils/db
How would I go about compiling Java files in these directories in to a runnable jar? I need to package required libraries into the generated JAR (jdbc).
I've always done these things in Eclipse but now I need to supply a couple of people with a way to compile the repository without the use of eclipse and I was thinking of making a makefile or a script that invokes the necessary javac pattern.
Take a look at Ant. It's a relatively simple build tool to understand, and provides everything that meets your requirements. Here's a quick skeleton build.xml to get you started:
<project name="my_app_name" default="jar">
<target name="compile">
<javac srcdir="src" destdir="bin">
<classpath>
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</classpath>
</javac>
</target>
<target name="jar">
<jar manifest="manifest_file" destfile="dist/my_app_name.jar">
<fileset dir="bin" />
<fileset dir="lib" />
</jar>
</target>
You need to create a manifest file that will tell the java process which class holds the "main" method. Here is a good place to start learning about manifests.
As an alternate that produces really cluttered Ant build files, you can right click on your Eclipse project and choose "Export...", then choose "General > Ant Buildfiles".
Anyway, that should get you started. You can ask more specific questions as you run into them.
First of all, consider using Ant for such a task.
But since you asked for a manual process, you need to first create a manifest file, like so:
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Class-Path: lib/jdbc.jar lib/otherlib.jar
Main-Class: com.name.app.MainClass
Replace the contents of Class-Path with your libs, and Main-Class with the fully qualified name of your main class.
Then, you need to generate the actual .jar, using the following command:
jar cfm app.jar MANIFEST.MF src/com/name/app/*.class src/com/name/app/do/*.class
Where MANIFEST.MF is the previously mentioned manifest file, and the rest is the folders where your .java classes lie in.
Finally, to run your app, you simply execute: java -jar app.jar.
Consider using Ant to do this. http://ant.apache.org/
I recommend that you use Apache Ant to implement your build scripts.
If implemented correctly, Ant is easy to use and the build scripts can be run on any platform that you can install a JDK on. Indeed, with a little bit of work, you can even set up your project so that users don't even need to download / install Ant. (Hint: add the Ant JAR files and a wrapper script to your project distro)