Java / Gradle - building a .jar file from .class files - java

I'm a newbie to Gradle. I'm tasked with writing a Gradle script / task that takes a bunch of precompiled .class and .properties files in a given directory (and all subdirectories thereof) and creating a single .jar file from them, manifest and all.
For example, if I were using Ant .xml script, I might do something like the following:
<target name="test" description="Build test.jar">
<exec dir="${testdir}" executable="cmd.exe " os="Windows 10">
<arg line="/c mkdir lib" />
</exec>
<jar destfile="${libdir}/test.jar">
<fileset dir="${testdir}/classes">
<include name="**/*.class" />
<include name="**/*.properties" />
</fileset>
</jar>
</target>
But I have no idea how to do something similar in Gradle. Would appreciate any help.
Edit: Running Gradle v.2.14.1, Groovy v.2.4.4

May be this one will be helpful.
Save in build.gradle and run by gradle zip
task zip(type: Zip) {
from 'app/classes'
include '**/*.class'
into('libdir/packed.zip') {
}
}
Source https://docs.gradle.org/current/userguide/working_with_files.html

Related

How to create a non executable jar in gradle

I am a beginner in gradle , I wanted to know is there a way to create a non executable jar using gradle task.
currently I have generated the jar using ant
<target name="build-jar">
<echo message="Creating jar"/>
<mkdir dir="${build}"/>
<jar destfile="${build}/lib/decouple-entity.jar"
basedir="C:/ProjectRelated/Decouple/consumer/bin/main/com/el/export"
includes="entity/** model/**"
/>
</target>
Any help would be great

Why combine all jars together?

I have create RESTful web service based on the JAX-RS and used Jersey embedded web server. My ant script compiles code successfully while it gives me error ClassNotFoundException when I run my main class. So after doing research I came up with solution & here it goes java build ant file with external jar files . What I did was created a bundled jar file try to execute that & it works perfectly fine. I want to know the reason behind :
why this solution works ?
Why I should combine all jar file ?
Is it similar to war file which we create following J2EE architecture otherwise war will not be extracted by server ( say TOMCAT ) & in my case jar file for Jersey embedded HTTP server?
EDIT:
Here is my ant build.xml file
<property name="lib.dir" value="${user.dir}/lib"/>
<property name="build.dir" value="${user.dir}/build"/>
<property name="build.lib.dir" value="${build.dir}/lib"/>
<property name="build.classes.dir" value="${build.dir}/classes"/>
<property name="src.dir" value="${user.dir}/src/main/java"/>
<property name="main.class" value="com.assignment.ConsoleServer"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="init" depends="clean">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="copy_jars" depends="init" >
<copy todir="${build.lib.dir}" >
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</copy>
</target>
<target name="compile" depends="copy_jars">
<javac srcdir="${src.dir}" destdir="${build.classes.dir}" classpathref="classpath" includeantruntime="false"/>
</target>
<target name="jar" depends="compile">
<jar destfile="${build.dir}/${ant.project.name}.jar" basedir="${build.classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
<zipgroupfileset dir="${lib.dir}" includes="*.jar"/>
</jar>
</target>
<target name="run" depends="jar">
<java fork="true" classname="${main.class}">
<classpath>
<path refid="classpath"/>
<path location="${build.dir}/${ant.project.name}.jar"/>
</classpath>
</java>
</target>
Here is my folder structure
P.S. I am not java expert so pardon me if this question is stupid.
Why this solution works?
In your particular case, you probably didn't include all of the necessary dependencies in your deployment in your previous. (It is not clear from your question how you were originally doing the deployment.)
Now you have put all of the application and dependent class files, etc into one JAR file, and presumably you are deploying / running that file. It works because now it has everything that it needs to run ... which it didn't before.
Why I should combine all jar file?
In your case I suspect that it was not strictly necessary. There was probably a way to "deploy" all of the dependencies without combining them into a single JAR file.
However, there is one case where a "uber-jar" has advantages. That is when the JAR is intended to be an "executable" JAR, and you want to be able to distribute / install it as a single file. (And executable JAR
file can refer to external JARs, etc, but the way that you have to do
it is "fragile".)
Is it similar to war file ... ?
Sort of, though a WAR file contains JAR files ... and typically other kinds of resources that the web-container understands.
The solution works because you packed all you service classes and depending libraries in one jar. That jar and everything inside will be in the class path and visible to your execution virtual machines class loader.
If you leave your depending libraries out your Jersey Web server needs to have them on it's class path, then you wouldn't get ClassNotFoundExcpetion
You shouldn't pack web application in single jar. You should crate war file where you dependencies will be placed inside WEB-INF/lib. You would easily then deploy that war on any application server. Switching to Maven instead of Ant can help a lot.
EDIT: After you added more details to description and ant
If you don't want to use fat-jar you can either
modify your antjava task to specify classpath that will reference
all external libraries (basically telling ant how to build
-classpath parameter for java -jar command
even better, modify your javac ant task by making complete Manifest file that specifies Class-Path correctly, take a better
look at the solution (at the bottom) of the answer you linked (java build ant file with external jar files)
For completness reference on Manifest here

How to add external .jar to android project? (with certain conditions)

I need to add some external .jar files to my android project BUT
1) without using Eclipse or any other IDE (so no .classpath)
2) without copying them to /libs folder, i need them to stay where they are
How can i accomplish that? I know that ant should have this functionality but and cant find it. It would be great if there is something like adding "android.library.reference" to project.properties but for .jar instead of library project.
i am not sure that it will work for you but you can use this
<path id="class.path">
<fileset dir="jar_folder">
<include name="**/*.jar" />
</fileset>
</path>
and you can use it in javac command as
<javac executable="${env.JAVA_HOME}/bin/javac" encoding="utf-8" srcdir="src/" destdir="temp/" debug="on" debuglevel="lines,source,var" fork="true" memoryInitialSize="256m" memoryMaximumSize="1024m">
<classpath refid="class.path" />
</javac>

Eclipse: Ant script to export User Library/Libraries for project

I am new to Java programming. I initially started with NetBeans but have moved to Eclipse given the advice from a friend.
In NetBeans, a pre-written ant build script for the project would generate a Project.jar file and place all required libraries/jars in a lib/ folder.
However, in Eclipse it appears that I need to write my own ant script. I have written a few lines to generate the jar file:
<target name="compile">
<mkdir dir="${build.dir}"/>
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="jars" debug="on"/>
</target>
How do I write a command to copy all of the jars in my User Library to a ${build.dir}/lib/ folder?
Thanks.
Use the copy task
like so, with the appropriate include or exclude pattern
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir">
<include name="**/*.jar"/>
</fileset>
</copy>
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
If you are new to Java take the chance to have a look at maven. It is a build tool like ant with a lot of predefined 'goals' and a fully developed dependency (to other libraries) handling. You will find a eclipse plugin which will be very useful.
Maven projects have a special directory layout which is kind of best practise and helpful for beginners. If you work on a maven project you can just use the command
mvn dependency:copy-dependencies
as a console command (or eclipse run configuration) to copy your project dependencies (libraries) to the <project>\target\dependency directory.
I recommend to use ant4eclipse library for ant based eclipse projects. When you use it, you can access eclipse workspace/project settings, and can iterate tought eclipse project class path in ant.
See the example code bellow:
<path id="ant.classpath">
<fileset dir="${lib.dir}/ant4eclipse">
<include name="*.jar" />
</fileset>
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<taskdef resource="net/sf/ant4eclipse/antlib.xml" />
<targetPlatform
<target name="copy_jars">
<getEclipseClasspath workspace="${basedir}/.."
projectname="TestProject"
targetPlatformLocation="c:/eclipse"
property="classpath"
relative="false"
runtime="true"
pathseparator="#" />
<!-- iterate over all classpath entries -->
<foreach list="${classpath}" delimiter="#"
target="copy_jar_file" param="classpath.entry" />
</target>
<target name="copy_jar_file">
<!-- check if current is a .jar-file ... -->
<if>
<isfileselected file="${classpath.entry}">
<filename name="**/*.jar" />
</isfileselected>
<then>
<!-- copy the jar file to a destination directory -->
<copy file="${classpath.entry}" tofile="${dest.dir}"/>
</then>
</if>
</target>
If you would like to use user libraries, you can define it by userlibraries command.

Exclude selected packages in jar command - build script

My project structure has these base packages.
a.b.c.core
a.b.c.web
a.b.c.common
And core,web,common packages will have sub packages. I have compiled all the java files under src dir and copied the class files to a dir.
<javac srcdir="${src}" destdir="${build}/myapp" debug="true">
<classpath refid="compile.classpath"/>
<classpath refid="ant.classpath" />
</javac>
Now i want to build a jar say core.jar with class files belonging to a.b.c.core and its subpackages. Similarly a web.jar and common.jar. Can someone give a sample code for jar task to accompolish this?
Thanks
Rather than excluding specific areas, I'd just include the ones you want:
<jar destfile="core.jar"
basedir="${build}/myapp"
includes="a/b/c/core/**"
/>
<jar destfile="common.jar"
basedir="${build}/myapp"
includes="a/b/c/common/**"
/>
<jar destfile="web.jar"
basedir="${build}/myapp"
includes="a/b/c/web/**"
/>
The jar task documentation is pretty good though... if the above doesn't do what you want, then that should help you.

Categories

Resources