Skip to content

oliviercailloux/Java-Archetype

Repository files navigation

Java Archetype

Usage

  • Type mvn archetype:generate -DarchetypeGroupId=io.github.oliviercailloux -DarchetypeArtifactId=java-archetype.

  • Enter your desired groupId and artifactId, press enter to accept the suggested package name, enter to confirm.

    • You have to change the suggested package name if the default one has invalid characters, such as hyphens! (Due to a bug in Maven archetypes, it seems difficult to support this use case. Please consider up-voting the bug, or commenting if you know anything relevant.)

  • Your project gets created in a subfolder of your current position, named from your artifactId.

Other usages

  • Use org.apache.maven.plugins:maven-archetype-plugin:3.2.1:generate instead of archetype:generate to use a specific (possibly more recent) version of the archetype plugin

  • mvn archetype:generate -DarchetypeGroupId=io.github.oliviercailloux -DarchetypeArtifactId=java-archetype -DinteractiveMode=false -DgroupId=mygroupid -DartifactId=myartifactid also indicates the desired group and artifact ids and remove the prompts.

From Eclipse

Eclipse looks at your local archetype catalog. You need to make this archetype appear there.

  • Invoke this archetype using one of the commands above. Maven will download it in your local repository (you should now see it under ~/.m2/repository/io/github/oliviercailloux/).

  • mvn archetype:crawl -Dcatalog=/home/username/.m2/archetype-catalog.xml asks Maven to create (or update) your local archetype catalog (more info).

  • In Eclipse: File / New / Maven Project, select this archetype.

From Eclipse (alternatives)

The following procedure uses the remote archetype catalog instead of the local one. The drawback is that it takes about 15 seconds each time you want to use this archetype, as Eclipse downloads the (huge) remote archetype catalog again each time. (Tested with Eclipse Neon, Oxygen and Photon.)

  • Window / Preferences / Maven / Archetypes / Add Remote Catalog…, give it the url http://repo1.maven.org/maven2/archetype-catalog.xml, Description: Remote archetypes catalog.

  • File / New / Maven Project, type cailloux in the filter box. Select this archetype.

Instead of using the Maven local or remote archetypes catalog as indicated above, you may prefer the Nexus Indexer: File / New / Maven Project, select Nexus Indexer as a catalog, type cailloux in the filter box. Select this archetype. (Tested under Eclipse Oxygen.) (On my install nothing appeared under Nexus Indexer, by default. Follow this to solve that problem.)

Generated projects

Projects generated from this archetype have the following characteristics.

How it works

  • I published this project to Maven Central (source on Maven Central visible here).

  • A few days later, the remote archetypes catalog indexed it.

  • When starting the archetype:generate goal, maven uses the org.apache.maven.plugins:maven-archetype-plugin plugin, which (by default) searches for archetypes in the remote archetypes catalog (see Archetype Catalog; you can also try mvn org.apache.maven.plugins:maven-archetype-plugin:3.2.1:generate -DarchetypeCatalog=local or mvn org.apache.maven.plugins:maven-archetype-plugin:3.2.1:generate -DarchetypeCatalog=internal for comparison).

  • One week later than publication, the Maven Central Index was updated. (Thus, there might be a delay between availability from maven command line invocation and availability within Eclipse, depending on the way you access archetypes.)

Alternatives

The official quickstart archetype

The official archetype (mentioned by Apache’s Maven Getting Started Guide and by the Apache Maven Cookbook) for simple Java projects is maven-archetype-quickstart, or org.apache.maven.archetypes:maven-archetype-quickstart in full.

It should, IMHO, be considered deprecated, as it suffers several weaknesses.

  • An important problem is that it creates projects that depend on JUnit 4. The current version, JUnit 5, differs significantly, providing among other an improved API.

  • Minor weaknesses: its default version is 1.0-SNAPSHOT, which should be 1.0.0-SNAPSHOT to follow the recommended and usual scheme.

  • Another minor weakness: it creates projects configured for a 1.7 JVM. This may be appropriate if you particularly need to support old installs, but opting for a reasonably recent JVM is a more reasonable default rule for new projects. For example, Java 8 introduced lambda expressions, which you probably do not want to miss out.

My archetype also provides logging by default, which I think is useful, scales better than sysout and does not hurt, and Guava, which usefully enriches Java.

Other quickstart archetypes in Maven Central

In order to join efforts if possible and avoid wasteful duplication, I actively searched for other archetypes that would have the same aim as this one: provide a simple archetype with reasonable defaults to easily start a modern Java project. (This was mostly done around June 2020.)

A general search on the internet led me to The Practical Developer. When contacted, he wrote to me (by e-mail) that he does not work on his archetype regularly and therefore preferred to decline collaborating on such a project.

As searches on the net did not reveal other useful results, and as I found no specialised search tool suitable for my needs, I implemented a simple archetype browser. It lists all the archetypes available in Maven Central. There are far too many to review manually, thus, I selected those whose groupId and artifactId existed since at least three years and have been updated during the last year, in hope of finding projects that are maintained on the long run, which I suppose indicates more probably a good quality project. (Of course this filter may have missed good quality archetypes that perfectly match the stated goal; I have no way to know. As a case in point, this very archetype does not pass that filter as I have changed its artifactId over time.)

I then filtered manually the resulting list on the basis of the archetypes descriptions found in their POM, and gave a further look (on the official website, typically) for a few promising archetypes among them. Only com.github.ngeor :archetype-quickstart-jdk8 revealed to be a suitable candidate. But its author wrote to me that he is “not really using/maintaing the archetype much these days”.

Please open an issue if you know other archetypes that aim at fulfilling a similar goal as this one.

Clean POM

I value clean configuration files, and this archetype provides a clean POM. By this, I mean that I value having as few configuration entries (or lines in my POM) as possible. This is important because the POM, as a fundamental description of your project, may be a source of subtle problems if it contains some incorrect entry; and such mistakes are much easier to notice when the file is very short.

This is one reason for not following the usual practice of defining the versions of all plugins that a project uses. (Another reason is spelled out below.) A counter-argument may be that such configuration lines can be moved away, for example in a parent POM, but this does not solve the problem of increased complexity; you still have as many (or more) total configuration entries in your project, only, with some of them hidden. Also, I do not define version properties, I rather keep the version where the dependency itself is declared, unless the property is required to avoid redundancy (see also this discussion).

About specifying versions

Here is a bit more rationale about my adoption of a “loose plugin dependency” strategy. By this, I mean that I do not specify precisely the versions of all plugins that I use. It is opposed to the “tight plugin dependency” strategy (example here). In general, the rationale of the tight dependency strategy is as follows: you tested your software with component C at version X; therefore, you declare that your software depends exactly on version X of component C, rather than declaring simply that it depends on (any sufficiently recent version of) component C.

The “tight dependency” strategy is usually recommended in order to avoid falling under a bug of a later version. Indeed, this is an advantage of that strategy. But I consider that this strategy should remain an exception rather than the norm. We ought to write software that relies on components described by general specifications, meaning, software that will work under future (or simply different) implementations of those specifications. We should not be content with guaranteeing only that our software works under this and that specific environment and version. Thus, we ought to write software that works with, for example, any future version of the maven-resources-plugin, not just one that works with version 2.6 of that plugin. Or, software that will work under future versions of the JVM. Or of Windows. (That is, as long as these components provide backwards compatibility.) The tight dependency strategy leads to extreme waste of resources, as it obliges end-users to have multiple versions of components available when their installed softwares require different versions of a single component. It also goes against the very spirit of program design by specification: future versions may improve performance or correct bugs, and specifying tight dependencies prevent your software from automatically benefitting from such improvements.

I admit that the industry tends, more and more, to apply the tight dependency strategy rather than the loose dependency strategy. I believe that this is an instance of a tragedy of the commons: it is better for an enterprise, locally, to specify dependencies tightly as it reduces the validity claims of its production; but it is worst for the ecosystem in general when actors behave in such a way.

To summarize, I believe that applying a loose dependency strategy produces higher quality software, and is doing the right thing for users and for good resource use. (Reasonable exceptions exist, of course, as always with such rules of thumb.)

References

(The reason I included Guava, JUnit and SLF4J in this archetype is because I personally think that these libraries are must-have in most projects, but it is good to see that popularity arguments go in the same direction.)

About

A maven archetype for starting Java projects

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages