Maven has a fairly standardized project structure and standard plugins for compilation and testing. Is there something widespread for Ant?
I found the following projects so far:
Antiplate
Ant Script Library
But I'm not sure whether these are widespread and are likely to be maintained in the future. Does someone have experience with them?
I know the guy who wrote Ant Script Library. He doesn't have any intention of stopping. To me, Ant's flexibility makes it hard for things like this to succeed. Ant-contrib only makes it worse IMHO as it allows people to break the model of the tool. Shame, as Ant is phenomenally powerful if you use it properly.
I have never heard of them. I've been on 2 significant Java projects lately. Our ant tasks were simple and home-grown. Each time someone starts a new project they make a copy of the ant file and mostly just change some constants at the top.
Related
I am a student and I hate not knowing how things are organized. I'd like to be able to create a full on java project from scratch on the command line. I'd like to be able to import jars and set the classpath, make packages and import them. ALso learn about environment variables. I currently do not know much about organizing code. I just know how to code in Java.
Is there a textbook, online article or the like that allows one to learn how to organize a java project?
I do not want any involvement with eclipse or any IDE. I am willing to learn Maven, XML, or the likes to accomplish my goal.
If you are a student willing to have a Java programming career, it might help to learn how to do things from command line, e.g. edit the files, compiling the classes, testing and building the project. Oracle tutorials provide example on this matter: https://docs.oracle.com/javase/tutorial/getStarted/cupojava/win32.html#win32-2
However, I strongly advise you to embrace an IDE as your Java career will mostly reside in an IDE as real life projects are BIG! There are tons of helpful things the IDE does to you out of the box or to simplify things. Since you are a student, I will give you one basic example besides compiling: a class with 10 fields requires you some typing for getters, setters, hashCode, equals. Alternative? Few keystrokes to instruct the IDE to generate them for you. And that's one basic example.
Regarding the project structure, embracing the (since you mentioned it) Maven project structure of src/main/{java,resources}, src/test/{java,resources} even if you do NOT use Maven. This will let you forget about organizing the files around.
If you were asking about structuring the classes in the right packages, you will figure out yourself as you gain experience. Rule of thumb is to group classes together by functionality they provide. Additionally, if the packages are organized right, if you change something and touching a few classes, ideally you'd want the changed classes to be located in a single package if possible.
Learning Maven is a good choice as it is a powerful tool for building a project and keeping things organized (project structure, project dependencies, etc.).
A simple Java program can be compiled trivially by javac MyMainClass.java, provided that your CLASSPATH list directories and jars with its dependencies.
Compiling a large Java project is not trivial. There are several tools intended to make it simpler.
Gradle: very widely used, uses its own language, very powerful and complex.
Maven: Still widely used. Uses XML to describe everything.
Apache Ant is lower level and lower abstraction power.
The power of these tools lies exactly in hiding the boilerplate of the Java project building process. They generate a skeleton of a build for you, and provide higher-level operations.
Of course you can start with simplest and watch the steps these tools make.
Reading the docs for javac and jar thoroughly does help, too.
I'd like to try using WebTest, preferably from Clojure, but I can only find its functionality exposed as Ant tasks. There seems to be some sort of Groovy interface, which implies that it's possible to use from any JVM language outside of Ant, but I can't figure it out.
I'm hoping to use WebTest as a "scriptable browser" to load up someone else's page and see if it does various unpleasant things, rather than test my own page with every build, so Ant doesn't really seem like an appropriate solution if I can avoid it.
It is often the case that useful Java functionality is hidden behind Ant tasks. I hit the issue when writing the book (pre-leiningen et al), and wrote lancet to let you call Ant tasks as clojure functions.
Lancet would probably need to be extended to handle arbitrary Ant tasks, but since it is now being maintained (as a dependency of leiningen) you might find other people willing to help out.
I am late into the game.
What about directly using the underlying httpunit java library straight from clojure ?
I have during the past months developed a Java project, a command-line experimental analysis tool. As I don't have a CS-major in the background (Mathematics/Engineering instead) I have had the pleasure of battling through and learning concepts such as project management & POM, version control (SVN) and build scripts (ANT). The reason why I am describing this is to portray the fact that most of these concepts don't come naturally to me, unlike algorithms and formulas (I guess one could say that I have learned to be a "coder" not a "programmer" if such a distinction is valid/accepted).
That being said, I have managed to make things work for the most part, however rather incomplete/ugly at times. As I would like to learn and improve along the way, I thought of asking here on SO. The ANT file that I use today, created with some help over time, is attached below.
Given the situation, I'd like to...:
Question 1: ... add version control to some extent so when I supply the software as a jar file to users worldwide, both they and I can have a way of tracking potential problems and development. Version number attached to the name of the JAR file (for ex: prog-0.1.5.jar), along with some sort of output to the user at runtime would be ideal. I was told that this was possible via ANT but I have not had any luck so far. Any tips or suggestions?
I have also received the following code snippet for this purpose, but I am not sure why/how it would work in my project as I have not declared these attributes/properties...
<svn>
<status path="."
lastChangedRevisionProperty="someproject.build" />
</svn>
EDIT: Just to clarify my long chunks of questions, I would like to standardize the version controlling in my project. I might be using the term in a wrong way, but the way version control is done right now is:
I do regular commits to an SVN server to track changes (and also to have backups)
I manually try to keep track of the different versions of software
To give an example of what I want to accomplish regarding versioning:
I would like to avoid manual version numbering; that's just so prone to errors...
I would like to keep track of the different builds, at the very least locally, using their version numbers, so at all times I have older build if I happen to need to investigate an older build. (I now do ant dist-clean; ant dist for new builds which just overwrite the old JARs)
It would be preferable if the version number could be incorporated into the build, so a informative line (e.g. "You are now running My_Awesome_software v:0.1.3") when the JARs are run
To accomplish the above with SVN as version tracking, and ANT as a build tool. I am not sure if I have the liberty to change the version tracking on our server, and Maven is just not an option at this stage. It appears to be more of a problem to learn mid-stream than whatever benefits it might have...
Question 2: ... look into unit testing. I have read a lot about unit testing being the holy grail of modern programming, and I have some distant memories of JUnit from university a few years back. I understand that in an ideal software development environment unit testing is absolutely critical, however I have no idea how unit tests should/could be implemented in my case; where the software has minimal user interface (a parameter file, and a couple of optional flags at runtime) and a LONG (read: hours) execution time in connection with the analysis.
Given the situation is it still considered a bad practice to not have unit tests, if that's the case how should I go about reasoning when I structure my tests?
I feel like the unit tests would typically be a couple of times larger, and execute even longer than the actual software if I tried to test most of the functions in the software.
conclusions: I have been looking into this version numbering concept using ANT, I'll shortly summarize my findings for other who might run into the same question:
Create a property file as #Kevin Stembridge mentioned below, e.g. build.properties. Mine looks like this:
micro.version=5
build.number=5
major.version=0
minor.version=0
Import properties from this file with: <property file="project-version.properties"/>
Concat the desired numbering scheme to the jar name in the jar tag. See the code below.
Unit testing is necessary, however complicated for a project like mine. I will look into it as the project develops.
Thanks to everyone who have contributed somehow, I am choosing Kevin's answer as accepted as it's the only one that had direct influence on my solution here.
<target name="dist" depends="compile,static" description="Compiles and builds jar files">
<mkdir dir="${dist}"/>
<buildnumber file="project-version.properties"/>
<property name="version.number" value="${major.version}.${minor.version}.${micro.version}"/>
<svn>
<status path="."
lastChangedRevisionProperty="rev.number" />
<info target="." />
</svn>
<jar basedir="${build}"
destfile="${dist}/fever-${version.number}-rev${rev.number}.jar"
includes="**/*" />
</target>
To answer question 1:
To add a version number to your jar and any other artifacts, you should create a properties file with a name such as "project-version.properties". In it add the following line:
project.version=<my_version_number>
In your build.xml file add the following snippet:
<property file="project-version.properties" />
Then you can append the version to your jar file like so:
<jar destfile="${dist}/prog-cli-${project.version}.jar">
To answer question 2:
Its a big discussion and I won't go into much detail. It is certainly possible (easier actually) to create a good suite of unit tests for code that has no user interface. If you know what output you expect to receive for a given input then you can write a test that confirms it.
To answer question 3:
Your build file looks fine. I don't see any problems with it.
Regarding the suggestion to use Maven. It will sort out your versioning issue for you by use of conventions but be aware that the learning curve is not the only downside. By switching to Maven you will be sacrificing flexibility, simplicity and reliablity.
I realize you are focused on Ant as a build tool. However, I would encourage you to consider Maven.
Some of the issues you describe are why Maven exists. The idea of unit testing before creating a JAR file, the idea of building in version numbers, the idea of branching and tagging a version within your source code repository (SVN even) are all built right into Maven.
The downside is that it is yet another tool to learn, and the learning curve can be steep.
1
The minute you have more than one version, you need version control!
If you don't have it, you will end up in "ah, version 4.5.1.2 source is in THAT zip-file" and it very quickly gets very tedious.
When you choose between version control systems, pick one that easily allow you to:
Embed a build-id with your application.
Use said build-id to easily get the exact source code corresponding to the build-id.
Do bug fixes to said source code.
This is commonly available today. Settle for no less. I personally happen to like git, and github, but others like mercurial and bzr.
2
Do not forget the reason for testing. You need to be told when things break, and as soon as possible! Frequently this means that you add a scenario that broke previously and was fixed, and then see if it breaks this time. You often do this in a build server which do the quick tests every time you check into your version system, and the long tests outside working hours.
3
I do not know if you should change stuff in your ant file, but I would encourage you to use an approach where the ant build file and the IDE configuration can be kept somewhat synchronized. I used ant4eclipse to write a build system using Eclipse configurations. This got quite gnarly and I would suggest using an IDE which explicitly knows about ant instead. I don't think this works well in Eclipse.
I'm working on a growing java project and I'm probably going to cooperate with somebody else to improve some features.
I'd like to use some tools to improve the quality of my work keeping in mind that:
I don't have too much time to spend on this project
it's a small project but it's really important for me
I don't want to buy software/hardware for it
I'm already using SVN
what do you think about maven and junit? is it worth spending time for them?
Do you know any other good tool?
Maven and JUnit are good for enforcing good habits (unit testing, uniform structure) and together with good SCM habits, I would say those are amongst the most important things for collaborative development.
Since you are not using JUnit my guess is you don't have any unit tests yet. This would seem to me the most important step for you to take, if other people will start working on your code. Without unit tests, someone can easily break functionality without knowing it.
Create a suite of unit tests that cover at least 80% of the code. You can use Cobertura to measure code coverage. This might seem like a lot of work (it is) but will save you far more time in the future.
Maven is the de-facto standard for building and deployment at the moment, but it has its drawbacks too. If you have a well documented build procedure in place (either using Ant or custom scripts) I would suggest it is less important to introduce Maven than to add unit tests.
JUnit is good for helping verify your code on any project.
Maven has a learning curve that can be hard to get over. If you have one module and a relatively simple set of build steps you may find it simpler to use Ant.
On the other hand with a Maven build you can simply add additional reports to your code to check various parameters on your code, and it is much harder to migrate to Maven than if you've conformed to its conventions from the start.
Examples of Maven plugins that can help check your code:
Findbugs (static analysis of possible bugs)
Checkstyle (enforce coding standards)
PMD (more static analysis)
PMD CPD (copy paste detection)
JDepend (cyclic dependency checking and package coupling)
Cobertura (code coverage)
If you're interested in the code quality plugins, also consider Sonar, it wraps these plugins up and gives you some funky reports.
If you're interested in best practice, also consider a Continuous Integration server, Hudson is free and integrates well with Maven.
We use Maven and JUnit on a fairly large project and find it very helpful.
For project planning, I highly recommend FogBugz. It's the best issue tracking system I have seen to date with good support for project management as well, and free for teams of up to 2 people.
If you use Eclipse and SVN I would recommend you to take a look at Mylyn. Its underlying concepts are very simple but it helps a lot when working on a team.
In my modest opinion, Maven is too annoying for the real benefit of it. Maybe ant is just enough for your deployment tasks.
I've used maven on one project and miss it. There is a fairly large upfront investment though in getting it setup and configured. The XML documentation was out of date when i was working with it (perhaps this has improved). Once you get past this initial setup though it's a wonderful time saver.
As for JUnit, it's great. Use it.
Both of these tools should be treated as an investment. At first it may seem like a lot of unrelated stuff, but the project will grow more predictably with less problems over the long haul.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What does another build tool targeted at Java really get me?
If you use Gradle over another tool, why?
I don't use Gradle in anger myself (just a toy project so far) [author means they have used Gradle on only a toy project so far, not that Gradle is a toy project - see comments], but I'd say that the reasons one would consider using it would be because of the frustrations of Ant and Maven.
In my experience Ant is often write-only (yes I know it is possible to write beautifully modular, elegant builds, but the fact is most people don't). For any non-trivial projects it becomes mind-bending, and takes great care to ensure that complex builds are truly portable. Its imperative nature can lead to replication of configuration between builds (though macros can help here).
Maven takes the opposite approach and expects you to completely integrate with the Maven lifecycle. Experienced Ant users find this particularly jarring as Maven removes many of the freedoms you have in Ant. For example there's a Sonatype blog that enumerates many of the Maven criticisms and their responses.
The Maven plugin mechanism allows for very powerful build configurations, and the inheritance model means you can define a small set of parent POMs encapsulating your build configurations for the whole enterprise and individual projects can inherit those configurations, leaving them lightweight. Maven configuration is very verbose (though Maven 3 promises to address this), and if you want to do anything that is "not the Maven way" you have to write a plugin or use the hacky Ant integration. Note I happen to like writing Maven plugins but appreciate that many will object to the effort involved.
Gradle promises to hit the sweet spot between Ant and Maven. It uses Ivy's approach for dependency resolution. It allows for convention over configuration but also includes Ant tasks as first class citizens. It also wisely allows you to use existing Maven/Ivy repositories.
So if you've hit and got stuck with any of the Ant/Maven pain points, it is probably worth trying Gradle out, though in my opinion it remains to be seen if you wouldn't just be trading known problems for unknown ones. The proof of the pudding is in the eating though so I would reserve judgment until the product is a little more mature and others have ironed out any kinks (they call it bleeding edge for a reason). I'll still be using it in my toy projects though, It's always good to be aware of the options.
Gradle can be used for many purposes - it's a much better Swiss army knife than Ant - but it's specifically focused on multi-project builds.
First of all, Gradle is a dependency programming tool which also means it's a programming tool. With Gradle you can execute any random task in your setup and Gradle will make sure all declared dependecies are properly and timely executed. Your code can be spread across many directories in any kind of layout (tree, flat, scattered, ...).
Gradle has two distinct phases: evaluation and execution. Basically, during evaluation Gradle will look for and evaluate build scripts in the directories it is supposed to look. During execution Gradle will execute tasks which have been loaded during evaluation taking into account task inter-dependencies.
On top of these dependency programming features Gradle adds project and JAR dependency features by intergration with Apache Ivy. As you know Ivy is a much more powerful and much less opinionated dependency management tool than say Maven.
Gradle detects dependencies between projects and between projects and JARs. Gradle works with Maven repositories (download and upload) like the iBiblio one or your own repositories but also supports and other kind of repository infrastructure you might have.
In multi-project builds Gradle is both adaptable and adapts to the build's structure and architecture. You don't have to adapt your structure or architecture to your build tool as would be required with Maven.
Gradle tries very hard not to get in your way, an effort Maven almost never makes. Convention is good yet so is flexibility. Gradle gives you many more features than Maven does but most importantly in many cases Gradle will offer you a painless transition path away from Maven.
This may be a bit controversial, but Gradle doesn't hide the fact that it's a fully-fledged programming language.
Ant + ant-contrib is essentially a turing complete programming language that no one really wants to program in.
Maven tries to take the opposite approach of trying to be completely declarative and forcing you to write and compile a plugin if you need logic. It also imposes a project model that is completely inflexible. Gradle combines the best of all these tools:
It follows convention-over-configuration (ala Maven) but only to the extent you want it
It lets you write flexible custom tasks like in Ant
It provides multi-module project support that is superior to both Ant and Maven
It has a DSL that makes the 80% things easy and the 20% things possible (unlike other build tools that make the 80% easy, 10% possible and 10% effectively impossible).
Gradle is the most configurable and flexible build tool I have yet to use. It requires some investment up front to learn the DSL and concepts like configurations but if you need a no-nonsense and completely configurable JVM build tool it's hard to beat.
Gradle nicely combines both Ant and Maven, taking the best from both frameworks. Flexibility from Ant and convention over configuration, dependency management and plugins from Maven.
So if you want to have a standard java build, like in maven, but test task has to do some custom step it could look like below.
build.gradle:
apply plugin:'java'
task test{
doFirst{
ant.copy(toDir:'build/test-classes'){fileset dir:'src/test/extra-resources'}
}
doLast{
...
}
}
On top of that it uses groovy syntax which gives much more expression power then ant/maven's xml.
It is a superset of Ant - you can use all Ant tasks in gradle with nicer, groovy-like syntax, ie.
ant.copy(file:'a.txt', toDir:"xyz")
or
ant.with{
delete "x.txt"
mkdir "abc"
copy file:"a.txt", toDir: "abc"
}
We use Gradle and chose it over Maven and Ant. Ant gave us total flexibility, and Ivy gives better dependency management than Maven, but there isn't great support for multi-project builds. You end up doing a lot of coding to support multi-project builds. Also having some build-by-convention is nice and makes build scripts more concise. With Maven, it takes build by convention too far, and customizing your build process becomes a hack. Also, Maven promotes every project publishing an artifact. Sometimes you have a project split up into subprojects but you want all of the subprojects to be built and versioned together. Not really something Maven is designed for.
With Gradle you can have the flexibility of Ant and build by convention of Maven. For example, it is trivial to extend the conventional build lifecycle with your own task. And you aren't forced to use a convention if you don't want to. Groovy is much nicer to code than XML. In Gradle, you can define dependencies between projects on the local file system without the need to publish artifacts for each to a repository. Finally, Gradle uses Ivy, so it has excellent dependency management. The only real downside for me thus far is the lack of mature Eclipse integration, but the options for Maven aren't really much better.
This isn't my answer, but it definitely resonates with me. It's from ThoughtWorks' Technology Radar from October 2012:
Two things have caused fatigue with XML-based build tools like Ant and
Maven: too many angry pointy braces and the coarseness of plug-in
architectures. While syntax issues can be dealt with through
generation, plug-in architectures severely limit the ability for build
tools to grow gracefully as projects become more complex. We have come
to feel that plug-ins are the wrong level of abstraction, and prefer
language-based tools like Gradle and Rake instead, because they offer
finer-grained abstractions and more flexibility long term.
Gradle put the fun back into building/assembling software. I used ant to build software my entire career and I have always considered the actual "buildit" part of the dev work being a necessary evil. A few months back our company grew tired of not using a binary repo (aka checking in jars into the vcs) and I was given the task to investigate this. Started with ivy since it could be bolted on top of ant, didn't have much luck getting my built artifacts published like I wanted. I went for maven and hacked away with xml, worked splendid for some simple helper libs but I ran into serious problems trying to bundle applications ready for deploy. Hassled quite a while googling plugins and reading forums and wound up downloading trillions of support jars for various plugins which I had a hard time using. Finally I went for gradle (getting quite bitter at this point, and annoyed that "It shouldn't be THIS hard!")
But from day one my mood started to improve. I was getting somewhere. Took me like two hours to migrate my first ant module and the build file was basically nothing. Easily fitted one screen. The big "wow" was: build scripts in xml, how stupid is that? the fact that declaring one dependency takes ONE row is very appealing to me -> you can easily see all dependencies for a certain project on one page. From then on I been on a constant roll, for every problem I faced so far there is a simple and elegant solution. I think these are the reasons:
groovy is very intuitive for java developers
documentation is great to awesome
the flexibility is endless
Now I spend my days trying to think up new features to add to our build process. How sick is that?
It's also much easier to manage native builds. Ant and Maven are effectively Java-only. Some plugins exist for Maven that try to handle some native projects, but they don't do an effective job. Ant tasks can be written that compile native projects, but they are too complex and awkward.
We do Java with JNI and lots of other native bits. Gradle simplified our Ant mess considerably. When we started to introduce dependency management to the native projects it was messy. We got Maven to do it, but the equivalent Gradle code was a tiny fraction of what was needed in Maven, and people could read it and understand it without becoming Maven gurus.
I agree partly with Ed Staub. Gradle definitely is more powerful compared to maven and provides more flexibility long term.
After performing an evaluation to move from maven to gradle, we decided to stick to maven itself for two issues
we encountered with gradle ( speed is slower than maven, proxy was not working ) .