Trying to understanding using Kotlin with Ant - java

<target name="build">
<delete dir="classes" failonerror="false"/>
<mkdir dir="classes"/>
<javac destdir="classes" includeAntRuntime="false" srcdir="src">
<withKotlin/>
</javac>
<jar destfile="hello.jar">
<fileset dir="classes"/>
</jar>
</target>
Kotlin Website
I am working on integrating Kotlin with my existing Java project (ivy and ant). Currently we use ivy.xml for dependency management and ant for build scripts.
If I used IVY, does it make specifying classpath="${kotlin.lib}/kotlin-ant.jar" redundant ?
I get an error org/jetbrains/kotlin/ant/antlib.xml not found in classpath. How to resolve it ?
How to add kotlin-ant.jar & and all its dependencies using using Ivy ?

If Ivy is used, then no need for specifying classpath="${kotlin.lib}/kotlin-ant.jar"
Regarding 2 & 3.
Create configurations for the Kotlin Dependencies in the ivy.xml
<configurations>
<conf name="kotlin" description="Kotlin Tasks"/>
</configurations>
<dependencies>
<dependency org="xxxxx" name="kotlin-ant" rev="xxxxx" conf="kotlin->default"/>
</dependencies>
In Build.xml, update the configuration.
<target name="resolve">
<ivy:resolve />
<ivy:cachepath pathid="kotlin.classpath" conf="kotlin"/>
</target>
<target name="build" depends="resolve">
<typedef resource="org/jetbrains/kotlin/ant/antlib.xml" classpathref="kotlin.classpath"/>
<kotlinc .....
</kotlinc>
</target>

Related

should we delete lib folder when we clean project in java and how to build it again after delete lib folder using apache ant and ivy

I have some problem, in my friend's code there is a clean code using apache ant seems to delete lib folder as well. but when I try to create project, it fails because the lib folder is missing. then how to build the correctly using ant apache ?
this is clean code
<target name="clean" description="--> clean the project">
<delete includeemptydirs="true">
<fileset dir="${basedir}">
<exclude name="src/**" />
<exclude name="build.xml" />
<exclude name="ivy.xml" />
</fileset>
</delete>
</target>
and this build code
<target name="build" description="Compile main source tree java files">
<mkdir dir="${build.dir}" />
<javac srcdir="${java.dir}" destdir="${build.dir}" classpathref="lib.path.id" debug="true" deprecation="true" optimize="true" failonerror="true" />
<!-- class path properties files -->
<copy file="${resource.dir}/log4j.properties" todir="${build.dir}" />
<copy file="${resource.dir}/mncplaymedia.properties" todir="${build.dir}" />
<copy todir="${build.dir}">
<fileset dir="${resource.dir}" />
</copy>
</target>
thank you
I think you have to build this project, then put the war or jar file in webapps on your web server (like jetty, tomcat and etc.)

Ivy dependency as provided

Problem: I need to have a lib on the eclipse classpath that should not be deployed to Tomcat. (In a maven project it would be scope provided)
Explanation:
I've setup a project with some Ivy dependencies and had to externalize a configuration as JNI (mail/session) in order to do it I had to put the mail-1.4.7.jar inside the Tomcat lib folder.
The problem is that I have a dependency that add to my classpath the javax.mail-1.5.2.jar so I change it to:
<dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2">
<exclude org="com.sun.mail" name="javax.mail"/>
</dependency>
The problem now is that my project break (compilation errors) because of missing mail classes such as javax.mail.MessagingException
So I have to add the mail dependency but only to eclipse. I've tried some configurations as explained here from what I know from Maven behavior with no avail.
Keeping the mail dependency only in the project, breaks Tomcat, keeping it on both tomcat and project breaks project. When I manually remove it from my project lib folder (WEB-INF\lib), after deploy the project, it works properly.
Bottom line (after deploy):
tomcatFolder
|_lib
| |_...
| |_mail-1.4.7.jar
| |_...
|_webapps
|_myproject
|_WEB-INF
|_lib
|_...
|_javax.mail-1.5.2.jar //need to remove it at deploy time only
|_...
Can't change it to maven right now. But it is in process :)
This is really a duplicate of this question:
How to copy runtime libraries without the provided ones in IVY
But.. from your question I suspect you're not using ivy configuration mappings. This is unfortunate because this is the mechanism used by ivy to logically group dependencies into functional groupings, similar to how Maven maintains scopes. The following posting attempts to bridge this understanding
How are maven scopes mapped to ivy configurations by ivy
Furthermore you are also using Eclipse, which means that unless you're using the ivy plugin you effectively have two build mechanisms. (ivy and eclipse). I would recommend fixing your ANT build first and then look at how to maintain the Eclipse classpath second.
Example
The first section describes how configurations are declared and used in the ivy file and the second section explains how the ivy ANT tasks are used in the build logic.
ivy.xml
You should always declare ivy configurations and use these to control your classpaths. In my builds I always have at least three: compile, runtime and test. Notice how the extends attribute is used to create relationships between the configs, because runtime should also include the compile dependencies.
Adding an additional one for the provided scope jars is easy. Simple stand-alone configuration:
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
<conf name="provided" description="Needed for compile, but will be present on the target platform."/>
</configurations>
<dependencies>
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>
<!-- runtime dependencies -->
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>
<!-- test dependencies -->
<dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
<!-- provided dependencies -->
<dependency org="org.apache.tomcat" name="servlet-api" rev="6.0.16" conf="provided->master"/>
</dependencies>
</ivy-module>
It's the configuration mappings that make things special. The simple explanation is that they fall into two basic types when pulling from a Maven repository:
conf="local_configuration->default"
conf="local_configuration->master"
The first means include the remote module and all its dependencies. The second means include the remote module and exclude it's dependencies. This means you don't need the following exclude trickery:
<dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2">
<exclude org="com.sun.mail" name="javax.mail"/>
</dependency>
You simply use the following, if all you want is the log4j-core jar:
<dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2" conf="provided->master"/>
Additional notes:
In ivy mapping to the remote "default" configuration will pull down only the jars you need. It will exclude optional dependencies and other stuff like javadocs.
Sometimes "excludes" are necessary when module authors get their dependencies wrong.
build.xml
The resolve target will pull down dependencies, generate a report and create the compile and test classpaths. Note the use of configurations to determine which jar groupings should be used:
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='${build.dir}/ivy-reports' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile,provided"/>
<ivy:cachepath pathid="test.path" conf="test,provided"/>
</target>
These classpath references are then used by the compile target as normal:
<target name="compile" depends="resolve,resources" description="Compile code">
<mkdir dir="${build.dir}/classes"/>
<javac srcdir="${src.dir}" destdir="${build.dir}/classes" includeantruntime="false" debug="true" classpathref="compile.path"/>
</target>
<target name="compile-tests" depends="compile" description="Compile tests">
<mkdir dir="${build.dir}/test-classes"/>
<javac srcdir="${test.src.dir}" destdir="${build.dir}/test-classes" includeantruntime="false" debug="true">
<classpath>
<path refid="test.path"/>
<pathelement path="${build.dir}/classes"/>
</classpath>
</javac>
</target>
And the test target:
<target name="test" depends="compile-tests" description="Run unit tests">
<mkdir dir="${build.dir}/test-reports"/>
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<path refid="test.path"/>
<pathelement path="${build.dir}/classes"/>
<pathelement path="${build.dir}/test-classes"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes" todir="${build.dir}/test-reports">
<fileset dir="${test.src.dir}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
</target>
Lastly the ivy retrieve task is used to build the war file. Only the "runtime" configuration jars are used:
<target name="package" depends="test" description="Create the WAR file">
<ivy:retrieve pattern="${build.dir}/lib/[artifact].[ext]" conf="runtime"/>
<war destfile="${war.file}" webxml="${resources.dir}/web.xml">
<fileset dir="${resources.dir}" excludes="web.xml"/>
<lib dir="${build.dir}/lib"/>
</war>
</target>
In conclusion the cachepath ivy task is used to create classpath references based on the ivy configurations and the retrieve task is used when assembling the war file.

Wrong usage of conf attribute of ivy

I think I donot understand well the conf feature of ivy even if I have read the tutorial. Think about I have two dependency;
guava.jar
foeu.jar
I need foeu.jar in compile time only but I need guava.jar not only in compile time but also in runtime. To implement these needs, I have wrote, in ivy.xml;
<configurations defaultconfmapping="runtime->compile">
<conf name="default"
visibility="public" />
<conf name="compile"
visibility="private"/>
<conf name="runtime"
extends="compile"
visibility="public"/>
</configurations>
and, dependency as;
<dependencies>
<dependency org="Google Guava" name="guava-17.0" rev="17.0"
conf="runtime->default"/>
<dependency org="Foeu" name="foeu" rev="5.5.1"
conf="compile->default"/>
</dependencies>
Really, something wrong with conf understanding of mine. What is the problem and what should I do?
UPDATE:
In build.xml, I am using it like;
ivy-initialization;
<target name="init-ivy" description="Initialize ivy requirements">
<property name="ivy.dep.file" value="${script.directory}/ivy/ivy.xml" />
<ivy:configure file="${script.directory}/ivy/ivyconf.xml"/>
<ivy:resolve/>
<ivy:cachepath pathid="ivy.compile.path" conf="compile" />
<ivy:cachepath pathid="ivy.runtime.path" conf="runtime" />
</target>
compile;
<target name="compile" depends="init-ivy" description="Compiling Java source codes with external libraries">
<javac compiler="javac1.7"
destdir="${class.directory}"
source="1.7"
target="1.7"
failonerror="true"
includeantruntime="false">
<src path="${source.directory}" />
<classpath refid="ivy.compile.path" />
</javac>
</target>
jar
<target name="create-jar" depends="compile" description="Creating jar files">
<jar destfile="${build.directory}/jar/${ant.project.name}.jar"
basedir="${class.directory}">
<manifest>
<attribute name="Main-Class" value="dataScience.management.Management"/>
</manifest>
</jar>
</target>
run
<target name="runtime" depends="create-jar" description="Running Java based application">
<java jar="${jar.directory}/${ant.project.name}.jar"
fork="yes"
maxmemory="400m">
<jvmarg value="-ea"/>
<classpath refid="ivy.runtime.path" />
</java>
</target>
Configurations are a tricky concept to understand. My recommendation is to create one for each functional group of dependencies in your build.
The bit you're looking for is the "extends" attribute. It enables membership inheritance. For example:
<configurations>
<conf name="compile" description="Libraries needed for compilation" />
<conf name="runtime" extends="compile" description="Libraries needed at runtime"/>
</configurations>
In this way all compile dependencies are automatically part of the runtime configuration.
For more detailed example take a look at the following answer:
Ivy, what is the master configuration and why is it not pulling jvyaml?
Update
This is not an ivy issue. Executable jars require main class and classpath to be present in the manifest file.
Build your jar file as follows:
<target name="build" depends="compile">
<ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]" conf="runtime"/>
<manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
<classpath>
<fileset dir="${dist.dir}/lib" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${dist.jar}" basedir="${build.dir}/classes">
<manifest>
<attribute name="Main-Class" value="${dist.main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
The ivy retrieve task populates a local dir with the runtime dependencies. The manifestclasspath task creates a list of relative links to these files and finally the "Class-Path" entry is added to the manifest file. You will then be able to run the jar as follows:
<java jar="${dist.jar}" fork="yes" maxmemory="400m">
<jvmarg value="-ea"/>
</java>
In conclusion there is basically two ways to run a jar. Specify the classpath and mainclass or create jar with the main class and classpath in the manifest.
Hope this solves your issue.

Ant include external .jar

I want to include external jar to my java project. I'm using ant. External .jar is in folder lib. My build.xml looks something like that:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<path id="classpath">
<fileset dir="lib" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build"/>
<javac srcdir="src" destdir="build" classpathref="classpath" />
</target>
<target name="jar">
<mkdir dir="trash"/>
<jar destfile="trash/test.jar" basedir="build">
<zipgroupfileset dir="lib" includes="**/*.jar"/>
<manifest>
<attribute name="Main-Class" value="com.Test"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="trash/test.jar" fork="true"/>
</target>
</project>
But it doesn't work. When I want to import something from the external .jar, there is an error after command ant compile: package com.something does not exist.. What should I edit to get it working?
Exact error:
Compiling 23 source files to xy/build
xy/src/com/Test.java:5: package com.thoughtworks.xstream does not exist
import com.thoughtworks.xstream.*;
^
1 error
You should try without the includes attribute:
<fileset dir="lib" />
And in the jar part you include the classes like this:
<zipgroupfileset includes="*.jar" dir="lib"/>
You can't put external libraries into a jar and expect the classloader to use those jars. Unfortunately this is not supported.
There are ant tasks like one jar that help you, to create a jar file, that contains everything you need.
This bit is from the background information of one jar:
Unfortunately this is does not work. The Java Launcher$AppClassLoader
does not know how to load classes from a Jar inside a Jar with this
kind of Class-Path. Trying to use
jar:file:jarname.jar!/commons-logging.jar also leads down a dead-end.
This approach will only work if you install (i.e. scatter) the
supporting Jar files into the directory where the jarname.jar file is
installed.
Another approach is to unpack all dependent Jar files and repack them
inside the jarname.jar file. This approach tends to be fragile and
slow, and can suffer from duplicate resource issues.
Other Alternative:
jarjar: Jar Jar Links is a utility that makes it easy to repackage Java libraries and embed them into your own distribution
I also use ant to include a number of dependency JARs in my JAR. My compile task looks like this. Perhaps something similar will work for you.
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" includeantruntime="false">
<classpath>
<pathelement path="${classpath}" />
<fileset dir="${deps}">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
<copy todir="${build}">
<fileset dir="${src}" excludes="**/*.java"/>
</copy>
</target>
sometimes u can use jar contents directly, just unzip
<unzip src="/Developer-Java/mysql-connector-java/mysql-connector-java-5.1.22-bin.jar" dest="${build_dir}" />

Ant built does not generate class files

I'm using build.xml to build my src. However it failed to generate class files without any error message. The full script is
<?xml version="1.0"?>
<project name="auxiliary" basedir="." default="dist">
<property name="src.dir" value="../auxiliary-src/com/nextbio/drugbank"/>
<property name="dist.dir" value="dist"/>
<property name="lib.dir" value="../jboss_config/common_app_jars"/>
<property name="temp.dir" value="temp"/>
<property name="foo_dist.dir" value="../foo/dist"/>
<path id="libs-classpath">
<fileset dir="${foo_dist.dir}">
<include name="foo.jar"/>
</fileset>
</path>
<target name="dist" depends="auxiliary-dist" />
<target name="auxiliary-cleanup">
<delete dir="${temp.dir}"/>
<delete dir="${dist.dir}"/>
<echo message="cleaned up. ${temp.dir}, and ${dist.dir} have been deleted."/>
</target>
<target name ="auxiliary-dist">
<delete dir="${temp.dir}"/>
<echo message="delete ${temp.dir}" />
<mkdir dir="${temp.dir}"/>
<javac destdir="${temp.dir}" source="1.6" target="1.6" debug="on" fork="true" memorymaximumsize="1024m">
<src path="${src.dir}"/>
<classpath>
<path refid="libs-classpath"/>
</classpath>
<include name="com/car/**"/> <!-- troubled line -->
</javac>
<!--<copy overwrite="true" todir="${temp.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
<exclude name="**/*.sql"/>
<exclude name="**/*.txt"/>
</fileset>
</copy>
<delete dir="${dist.dir}"/>
<mkdir dir="${dist.dir}"/>
<jar destfile="${dist.dir}/auxiliary.jar" basedir="${temp.dir}"/> -->
</target>
There is no class file in ${temp.dir} after this step, and no error message. I double checked it, and found it is because of the "troubled line". I tried to add some files to the classpath. I don't know why it is wrong.
The source path should point to the root of the package tree. You make it point to a specific package inside the sources : ../auxiliary-src/com/nextbio/drugbank.
And in the javac task, you ask it to compile all the files matching the pattern com/car/**. That means that it will compile the Java source files in ../auxiliary-src/com/nextbio/drugbank/com/car or in a subdirectory. If that's the case, you have very unconventional package names.
I had the same problem.
My project complilated well but the classes there weren't in nowhere and It didn't have any error message.
My problem was the classpath. The eclipse wizard added EclipseLink 2.5.1 jars.
I removed it and the problem is gone.
I suggest make a simple HelloWord and remove all jars
reference from the classpath and try again.
I encountered this "ant, javac, compile" problem related with the classpath to.
No debug or verbose message shown.
This behavior appear because in classpath exists not compatible (superior) version jar packages and that cause no output classes.

Categories