This is just a notes-to-self blog post that documents some basic processes related to writing simple Java applications. I need to go through all this somewhat regularly, but not regularly enough that I remember the details off the top of my head, so it's time to write it down.
Maven seems the most widely used build/dependency management tool. In practice, I've found it easier to leverage Maven than try and work with
javac directly, even for quick little test projects. As a bonus, it scales to even the most complex of scenarios.
I avoid using IntelliJ for small projects because I don't want to add another layer of complexity and I like the VS Code editing experience better. The Java intellisense etc in VS Code is pretty good these days and so overall I think it's a better solution for small projects.
To create a new project:
You can specify various parameters as arguments, or if you don't you'll be prompted for what's needed. That's most convenient here if you're not trying to automate something.
The first question is which project archetype (template) to use. The default is
maven-archetype-quickstart) which is perfect for a simple console application. You'll be asked for what version of the archetype to use - the default here is
1.4, go with that.
Next, you'll need to specify the project
com.mhowlett) which together with the
artifactId (specified next, e.g.
test-project) is intended to uniquely identify your project across all projects. The groupId and artefactId are what you use to specify your project as a dependency in another project's
pom.xml file. The artifactId is also the name of the jar file minus the version suffix. After groupId and artifactId, you'll be asked for a version, which defaults to
1.0-SNAPSHOT. That's fine.
Finally, you'll be asked for a package name which will be used to generate the initial directory structure of your project. Usually you should make this align with the
groupId, but it doesn't need to. A package is simply a namespace. A given
.jar file can contain any number of packages.
If you want Java 8 (rather than Java 7), update the
maven.compiler.target tags in the generated
You can build your package with:
You can 'install' your package in the local cache, making it accessible as a dependency for other local projects with:
Add the following to the generated
pom.xml file under
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <mainClass>com.mhowlett.App</mainClass> </configuration> </plugin>
(replacing the value of
Now you can run your application with the following:
I sometimes need to specify a local fat jar dependency (which in turn contains shaded dependencies). There are various ways to do this, but the method I've been using is to install the fat jar in the local maven cache:
mvn install:install-file -Dfile=the-jar-file.jar -DgroupId=the.group.name -DartifactId=the-artifactid -Dversion=<version> -Dpackaging=jar
and then just specify the dependency as normal in the
Note that I'm using an artifactId for the fat jar which is different from the original jar's artifactId.
Sometime I need to inspect the contents of a .jar for debugging purposes. To do this:
jar tf jar-file
And to extract the contents of a .jar:
jar xf jar-file
That's it! Already more than I really wish I needed to know about the Java ecosystem :-).
Side note: Java could learn a thing or two from C#/.NET Core here - the Java way seems overly complicated by comparison.