NPE from AttachedArtifact.getVersion rather than meaningful error
-----------------------------------------------------------------
Key: MNG-4731
URL: http://jira.codehaus.org/browse/MNG-4731
Project: Maven 2 & 3
Issue Type: Bug
Components: Errors
Affects Versions: 2.2.1
Environment: Ubuntu Lucid, JDK 6u21
Reporter: Jesse Glick
Attachments: validateIdentity.diff
I am working on a problem with {{nbm:populate-repository}} (from
{{org.codehaus.mojo:nbm-maven-plugin}}). Maven 2.2.1, when run under certain
circumstances, fails when running this goal with the following unhelpful
message:
{noformat}
...
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] null
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NullPointerException
at
org.apache.maven.project.artifact.AttachedArtifact.getVersion(AttachedArtifact.java:122)
at
org.apache.maven.artifact.DefaultArtifact.validateIdentity(DefaultArtifact.java:141)
at
org.apache.maven.artifact.DefaultArtifact.<init>(DefaultArtifact.java:122)
at
org.apache.maven.project.artifact.AttachedArtifact.<init>(AttachedArtifact.java:42)
at
org.codehaus.mojo.nbm.PopulateRepositoryMojo.createAttachedArtifact(PopulateRepositoryMojo.java:617)
at
org.codehaus.mojo.nbm.PopulateRepositoryMojo.execute(PopulateRepositoryMojo.java:424)
...
{noformat}
Inspection of the code reveals the immediate cause of the NPE: in
{{getVersion}}, the {{parent}} field is null. Even though this is a final field
set in the constructor to a non-null value, it has not yet been set when the
super constructor is called. This is because {{DefaultArtifact}} uses the
antipattern of calling an overridable method ({{getVersion}}) from its
constructor (indirectly via {{validateIdentity}}). The NPE then prevents the
details of the problem from being reported to the user.
Ideally this antipattern would be solved, by making {{validateIdentity}} public
and requiring all creators of a {{DefaultArtifact}} to call it after
construction. Since this cannot now be done compatibly (e.g.
{{PopulateRepositoryMojo}} above would need to be modified), the next best
thing is to assume that {{AttachedArtifact}} is the only subclass, and ensure
that {{validateIdentity}} is called only once the object has been fully
constructed. With that change (patch against {{2.2.2-SNAPSHOT}} attached), the
error message is informative (specifics of this run have been elided) and
points toward possible problems in the plugin:
{noformat}
...
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] An invalid artifact was detected.
This artifact might be in your project's POM, or it might have been included
transitively
during the resolution process. Here is the information we do have for this
artifact:
o GroupID: ...
o ArtifactID: ...
o Version: ...
o Type: <<< MISSING >>>
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.artifact.InvalidArtifactRTException: For artifact
{...:...:...:null}: The type cannot be empty.
at
org.apache.maven.artifact.DefaultArtifact.validateIdentity(DefaultArtifact.java:141)
at
org.apache.maven.project.artifact.AttachedArtifact.validateIdentity(AttachedArtifact.java:63)
at
org.apache.maven.project.artifact.AttachedArtifact.<init>(AttachedArtifact.java:53)
at
org.codehaus.mojo.nbm.PopulateRepositoryMojo.createAttachedArtifact(PopulateRepositoryMojo.java:617)
at
org.codehaus.mojo.nbm.PopulateRepositoryMojo.execute(PopulateRepositoryMojo.java:424)
...
{noformat}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira