The Maven POM has an element, ${}, that specifies the name of the artifact file. finalName overrides the default name: "${artifactId}-${version}".

Today, finalName is typically used when it's important for technical reasons that the artifact not include a version number. For example, Java WAR files typically load into a virtual directory named after the WAR, but we don't want the URL of the website to change when we change the version number of the WAR file.

Unfortunately, today, artifacts in the local repository always use the default name and never honor the finalName specified in the POM. e.g. the war artifact "foo" version "1.0" is stored as "foo-1.0.war" in the local repository, even if its finalName is just "foo".

Under this proposal, if a ${} is specified, the file in the local repository would have that name, e.g. just "foo.war".

Justification: Windows Libraries

The finalName is especially and uniquely important for Windows libraries.

Windows has no symlink feature and no automated LD-style re-linker. Therefore, Windows libraries (DLL files) must have the same name at build-time and at run-time; DLLs will not work if they are renamed after they are built (unless they are re-renamed back to their build-time names).

Suppose you have two libraries: "myBusinessLogic" and "myUI", where myUI depends on myBusinessLogic. If you build myBusinessLogic under the name "myBusinessLogic-1.0.dll", then it's impossible to replace it with "myBusinessLogic-1.1.dll".

In other words, if you need to upgrade your DLLs at runtime, you have to build them without version numbers in their names.

Today, even if you specify an unversioned <finalName> for your DLL, the DLL in the local repository will have the wrong (versioned) name.

Objections to Windows libraries

For some odd reason, arguments from Windows libraries have been very controversial. Here are some common arguments and rebuttals.


This change is pretty simple, except for one important detail. Today, all copies of 1.0-SNAPSHOT are stored in the same directory, as foo-20090905.194035-1.jar. If all of those files were just called "foo.jar", they would conflict with each other.

So, instead, the 1.0-SNAPSHOT directory in the local repository should change to contain a "20090905.194035-1" subdirectory. Within that, you can put "foo.jar". A sibling directory "20090905.194036-2" could contain its own copy of "foo.jar" and so on.