gradle - attach source jar file to depenency - java

I have a project with both maven depedencies and a dependency on an company-internal jar file stored in our company's ivy repository. It was published with an ivy ant task. Let's call this file myco.jar. there is a source file called myco-sources.jar, and it is in the same location as myco.jar.
When I build with gradle, via Eclipse, the maven dependencies automatically download the source jar file and attach it to the main jar in the generated .classpath file. But for myco.jar, it does not automatically attach myco-sources.jar to it. Instead, myco-sources.jar is downloaded as if it was a separate dependency. So even though the source code is technically part of the classpath, I still can't step through the source code when debugging!
Here's a snippet of my dependencies:
dependencies {
implementation "com.myco:modname:${versionNo}"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jacksonVersion}"
...
}
How do I 'tell' gradle that the sources file is not a separate dependency but is the source file for the myco.jar file?
This is how the ivy.xml file looks like that is used to publish the myco.jar and myco-sources.jar files:
<publications>
<artifact name="myco" type="jar" ext="jar"/>
<artifact name="myco" e:classifier="sources" type="source" ext="jar"/>
<dependencies>
<dependency ... />
...
</dependencies>
and this is the ant task CI runs to publish to our artifactory repository:
<target name="publish-task" depends="xxx" description="xxx">
<ivy:resolve file="ivy.xml"/>
<ivy:publish pubrevision="${version}" status="integration" resolver="xxx" overwrite="true">
<artifacts pattern="${path}/[artifact]-[revision](-[classifier]).[ext]"/>
</ivy:publish>
<delete file="ivy-${version}.xml"/>
</target>

Related

WSDL file to Jar File

I have WSDL file URL and I want to create JAR file and need use in another project.
I have try to convert with below scenarios
1.Using wsimport command to Java files and using this java files create maven project as packaging JAR
wsimport -keep -wsdllocation /MyService.wsdl
2.Using ANT build (create build.xml file create target for export JAR)
<target name="dist" depends="compile" description="generate the distribution">
<buildnumber />
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib" />
MyApplication-${version}.${build.number}.jar -->
<jar destfile="${dist}/lib/MyApplication-${version}.${build.number}.jar" basedir="${build}" />
</target>
above both scenarios JAR exported but when I deployed in server getting below Exception
java.lang.NoClassDefFoundError
what I am doing wrong ?
is there any simple way to convert wsdl to Jar?
This Issue occur run time class not found.
I have add new Assembly in Eclipse -> specific project -> Web Deployment Assembly
select specific JAR,WAR,RAR or ZIP file from path and set.
and test again after this solved this issue.

Loop over ANT properties with same prefix (and extract suffix)

I handle the build of a Java product with dependencies with ant.
Here is my project.properties file:
project.name=foo
project.version=1.0.0
thirdpart.commons-cli.version=1.2
thirdpart.guava.version=16.0.1
This is loaded using the following in my build.xml ant script:
<property file="project.properties"/>
I would like to loop over all properties starting by "thirdpart." and retrieve each time the name between "thirdpart." & ".version" and the value of the property.
Idea behind is then to retrieve the correct jar file from a shared server. Those informations will help me to build up the correct URL to retrieve them, while allowing me to change my dependencies version easily.
How to proceed with ant ? (Thanks for your help).
Instead of building your own dependency manager I would suggest using Apache ivy.
Several advantages. Instead of building and populating a shared server, you could download from Maven Central. Standard Maven repository managers (nexus, artifactory, archiva) can be used to host repositories inside your firewall.
Examples:
Class not found with Ant, Ivy and JUnit - error in build.xml?
How to avoid copying dependencies with Ivy
Your dependencies
Here's an example ivy.xml file to retrieve your dependencies
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile" description="Required to compile application"/>
</configurations>
<dependencies>
<!-- compile dependencies -->
<dependency org="commons-cli" name="commons-cli" rev="1.2" conf="compile->default"/>
<dependency org="com.google.guava" name="guava" rev="17.0-rc2" conf="compile->default"/>
</dependencies>
</ivy-module>

Java - How to create JavaDocs in Apache Ivy

I know how to create javadocs for my source file in Apache Ant Build.
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
But I don't know how to create them in Apache Ivy.
Could some one show me a sample example ?
Apache Ivy is a dependency management library for use with (not a replacement for) Apache Ant. Therefore, you will use the same <javadoc> task as always.
Apache Ivy is a dependency manager that works with Ant (a build manager). Apache Ivy is usually (or possible always?) used with Ant to handle builds. Since javadoc creation is a build task not a dependency task, it wouldn't make sense to generate javadocs using Ivy.
It looks like you're going around in a circle here. Ivy works with Ant. You still have a build.xml file that you use for your builds. The ivy.xml file simply contains a list of the third-party jars your project needs in order to build. Thus, the direct answer to your question would be:
Put the following in your build.xml:
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
When you use Ivy, you still use Ant. And, you still have a build.xml file. And, you still write compose your build with various Ant tasks.
Download this project. It's a simple build that contains three class files and a build.xml file. You will notice there's a jar directory with the following two jars:
commons-logging-1.1.1.jar
spring.jar
If you look at lines 36 to 40 of the build.xml file, the project is creating a compile classpath like this:
<path id="java">
<fileset file="jar/spring.jar"/>
<fileset file="jar/commons-logging-1.1.1.jar"/>
</path>
So, when he compiles, he does this:
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Now, let's look at how this may change with Ivy. In Ivy, I create a ivy.xml file that contains a description of what jars I need. However, I only have to specify classes I use directly. In this case, I only need the spring.jar. Here's my ivy.xml:
<ivy-module version="1.0>
<info organisation="com.seantheflexguy"
name="ContextExample"
revision="1.0"/>
<configurations>
<conf="default" visibility="public"/>
<conf="compile" visibility="public"/>
</configurations>
<dependencies>
<dependency org="org.springframework" name="spring"
rev="2.0.4" conf="compile->default"/>
</dependencies>
</ivy-module>
Now, instead, of using the jars in the jar directory, I'll have Ivy construct the classpath:
<ivy:resolve/>
<ivy:cachepath pathid="java"/>
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Notice instead of using the <path> task to create a classpath, I use two Ant tasks that Ivy uses. The <ivy:resolve/> looks at my ivy.xml and resolves my dependencies on the jars I request. These jars will be downloaded into my $HOME/.ivy2/cache directory.
The <ivy:cachepath> task creates a classpath I'm calling the classpath java because that's what it was previously called.
With those two Ivy tasks, I've created a classpath that I can use with the <javac> task. In fact, I'm not even bothering to change the <javac> task.
So, in Ivy:
I still need my build.xml. It's how I define the various build tasks I need to do. In fact, Ivy defines even more Ant tasks I need in my build.xml file.
The ivy.xml file simply defines my jar dependencies. When I implement Ivy in this project, I can delete the jar directory.
Does this help you understand how Ivy works?

How to configure Ivy for Ant build

I currently have ANT_HOME located at /home/<myuser>/ant/1.8.4/ant-1.8.4.
I just downloaded the Apache Ivy tarball that includes its dependencies. I extracted it to /home/<myuser>/ivy/2.3.0-rc1/ivy-2.3.0-rc1.
I then copied /home/<myuser>/ivy/2.3.0-rc1/ivy-2.3.0-rc1/lib/*.jar to ANT_HOME/lib. If my understanding of how Ant works with plugins/extensions is correct, then Ant should now be able to access all of Ivy's tasks at runtime.
My next question is, how do I define Ivy tasks inside my Ant buildfile? Say I want to use ivy-retrieve, ivy-resolve and ivy-publish tasks. What are all the configurations I need to do (in the XML) to get these tasks working when I run my Ant build from the command-line (I will not be building through the Ant-Eclipse plugin). Thanks in advance!
First, you have to define a <taskdef> to point to the Ivy tasks.
<property environment="env"/>
<property name="ivy.home" value="${env_IVY_HOME}"/>
<taskdef resource="org/apache/ivy/ant/antlib.xml">
<classpath>
<fileset dir="${ivy.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</taskdef>
That will give you access to the Ivy tasks. You'd use these tasks like this:
<cachepath pathid="main.classpath" conf="compile"/>
The problem is that your Ivy tasks names might clash with other Ant tasks. For example, there's an Ivy task <report>. To solve this, you can create an Ivy namespace. To do that, you put a reference in your namespace in the <project> entity like this:
<project name="my.proj" default="package" basedir="."
xmlns:ivy="antlib:org.apache.ivy.ant"/>
Now, when you define the Ivy tasks, you can use that antlib:org.apache.ivy.ant reference to your ivy namespace. Same taskdef as before, but with a uri field:
<property environment="env"/>
<property name="ivy.home" value="${env_IVY_HOME}"/>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant">
<classpath>
<fileset dir="${ivy.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</taskdef>
By the way, there's nothing special about that uri. I could have done this:
<project name="my.proj" default="package" basename="."
xmlns:ivy="pastrami:with.mustard">
[...]
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="pastrami:with.mustard">
<classpath>
<fileset dir="${ivy.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</taskdef>
The point is now you can prefix your task names with ivy:. Instead of this:
<cachepath pathid="main.classpath" conf="compile"/>
You can now do this:
<ivy:cachepath pathid="main.classpath" conf="compile"/>
And that's how you gain access to your Ivy Ant tasks.
Now, you have access to your Ivy Ant tasks, you need to define an ivysettings.xml file and use the <ivy:settings/> task to point there:
<ivy:settings file="${ivy.home}/ivysettings.xml"/>
There is a default ivysettings.xml file embedded in Ivy that will point you to the world wide Maven repository system. If you don't have a company wide Maven repository, then you can use the default ivysettings.xml file:
<ivy:settings/>
That's pretty simple.
Once you've done that, you need to read in and resolve your ivy.xml file which usually sits in the root of your project in the same directory as your build.xml file.
Basically, your ivy.xml file contains references to the third party jars you want to bring into your project. For example:
<dependencies>
<dependency org="log4j" name="log4j" rev="1.2.17" conf="compile->default"/>
<dependency org="junit" name="junit" rev="4.10" conf="test->default"/>
</dependencies>
What this is saying is that I need the log4j.jar (revision 1.2.17) for compilation (and for compiling tests too) and I need junit.jar (revision.4.10) for compilation of my test code.
The compile->default is a mapping of my compile configuration to Maven's default configuration (which says I just want the Jar and any other jars that it might depend upon.
Where's does my compile configuration come from? I define it in my ivy.xml. There are ten standard configurations. This also goes into your ivy.xml file:
<configurations>
<conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
<conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
<conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
<conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
<conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
<conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases." extends="runtime"/>
<conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
<conf name="sources" visibility="public" description="this configuration contains the source artifact of this module, if any."/>
<conf name="javadoc" visibility="public" description="this configuration contains the javadoc artifact of this module, if any."/>
<conf name="optional" visibility="public" description="contains all optional dependencies"/>
</configurations>
You can use any configuration name you want, but these map to the default Maven configurations and are widely used.
Once you have your ivy.xml file defined, you can use <ivy.resolve> to resolve your dependencies:
<ivy:resolve/>
So, we have the following:
How to use <taskdef> in your build.xml to incorporate the Ivy Ant tasks into your build.
How to use the Ivy Ant task <ivy:settings> to configure Ivy.
How to use <ivy:resolve/> to read in your ivy.xml file and resolve your third party jar dependencies.
Now, you probably want to actually use those jar files. There are three ways to do this:
<ivy:cachepath pathid="main.classpath" conf="compile"/>
The <ivy:cachepath/> task will create a classpath (in this case called main.classpath) that points to the jars you have in your ivy.xml file's compile configuration. This is used most of the time.
If you need a fileset, you can use this:
<ivy:cachefileset setid="compile.fileset" conf="compile"/>
In this case, it will create a fileset with a refid of compile.fileset.
Sometimes you have to bring the jars into your project. For example, if you create a war or ear file, you want to enclose your jars. In that case, you can use this:
<property name="lib.dir" value="${target.dir}/lib"/>
<ivy:retrieve pattern="${lib.dir}/[artifact].[ext]"
conf="runtime"/>
That will fetch your jars into the ${lib.dir} directory, so you can include them in wars or ears.
Sorry for the long answer, but there are a lot of steps to cover. I highly recommend Manning's book Ant in Action which has a whole chapter on Ivy.
David gave a very fine answer, but I'd like to point out that the taskdef is not required.
Provided the ivy.jar is in the expected location the namespace declaration at the top of the ANT file is enough:
<project ..... xmlns:ivy="antlib:org.apache.ivy.ant">
For more detail I'd recommend reading about how ANT libs work.
The following answer provides some more "setting up ivy" advice:
Ivy fails to resolve a dependency, unable to find cause

Do I need to set up Maven to be able to use Maven ant dependency task?

I was following these steps -
http://maven.apache.org/ant-tasks/examples/dependencies.html
and got through. I have a silly question that do I need maven to be set up on my system to be able to use it?
No. As per the installation docs:
Maven Ant Tasks and all its dependencies are packaged together as a single JAR file.
The below works fine for me with the tasks jar in $ANT_HOME/lib and no M2_HOME set, no mvn executable on my path, and an empty $CLASSPATH:
<project name="test1" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<path id="maven-ant-tasks.classpath" path="lib/maven-ant-tasks-2.1.3.jar"/>
<typedef resource="org/apache/maven/artifact/ant/antlib.xml"
uri="antlib:org.apache.maven.artifact.ant"
classpathref="maven-ant-tasks.classpath"/>
<target name="get">
<artifact:dependencies pathId="dependency.classpath">
<dependency groupId="junit" artifactId="junit" version="3.8.2" scope="test"/>
</artifact:dependencies>
</target>
</project>
If I clear out 3.8.2 from my ~/.m2 repo directory, the artifact is downloaded properly.

Categories

Resources