bnd icon indicating copy to clipboard operation
bnd copied to clipboard

[mvn] Maven bundle info overwritten with project info

Open kriegfrj opened this issue 8 months ago • 7 comments

I hit upon a strange issue just now.

I did a number of things in quick succession and ended up with a number of weird things happening. I am trying to capture as much information while it is fresh in my mind as I am not sure at this stage what actually caused the issue.

  • I had two Maven Central repos (pointing at Maven Central for releases, Sonatype for snapshots). -plugin.05 with index file build.mvn was for build dependencies, -plugin.06-> runtime.mvn for runtime dependencies.
  • I added depency org.jvnet.mock-javamail:mock-javamail:2.2 to my build.mvn .
  • Bndtools reported that the org.jvnet.mock-javamail:mock-javamail:2.2.0 was not found. I realised that the dependency was not in Maven Central but on Jenkins.
  • Renamed the existing -plugin.06 to -plugin.07 and added a new MavenBndRepository for the Jenkins repo:
 -plugin.06.jenkins: \
    aQute.bnd.repository.maven.provider.MavenBndRepository; \
        releaseUrl=https://repo.jenkins-ci.org/releases/; \
        index=${.}/jenkins.mvn; \
        readOnly=true; \
        name="Jenkins"
  • Bndtools started rebuilding and came up with a build error, the root exception being and "Already closed" exception on the newly-added Jenkins repo.

This error was almost certainly a concurrency issue due to the number of repo changes I made in a short period of time - during which the BndtoolsBuilder was dutifully trying to rebuild my workspace and keep it up-to-date with the changes. I had to restart Eclipse to make it go away.

Now, even after I restarted Eclipse, I noticed that it was repeatedly re-building the bundle to which I had added my new dependency. I had to remove the dependency to get it to stop, and re-adding it caused it to start again.

I found that the jar in my local Maven cache had been overwritten with a jar that had merged in the metadata from my project - in particular, the BSN was set to the BSN of the project that included it on the build path. It was also being listed under my Jenkins maven repo with this BSN instead of the original Group-Artifact coordinate (as non-bundles are normally displayed). This may have had something to do with the fact that my -buildrepo is also pointing at the my local maven repo.

Possibly relevant: my project had an -includeresource: @${repo;org.jvnet.mock-javamail:mock-javamail;2.2.0} directive. Commenting this out also seemed to stop the re-build.

Deleting the dependency from jenkins.mvn, and clearing the artifact from my .m2 directory, and then re-instating it seemed to fix everything.

So it seems the sequence of events was:

  • Something unusual happened that caused the artifact to get overwritten in the first place.
  • Once overwritten, Bnd was confused about where to put the output of my project due to the fact that the dependency mock-javamail dependency and my project's bundle had identical BSNs, and then every time it ran it overwrote the mock-javamail dependency in my .m2 cache, which in turn triggered a rebuild.

So the root problem seems to be that Bndtools overwrote the artifact for no apparent good reason. Once it was overwritten the behaviour is understandable, but I can't see any reason why Bndtools should have overwritten the artifact in the first place.

kriegfrj avatar Apr 02 '25 00:04 kriegfrj

  • the fact that the dependency mock-javamail dependency and my project's bundle had identical BSNs

Could you elaborate on this sentence a bit more?

chrisrueger avatar Apr 02 '25 04:04 chrisrueger

  • the fact that the dependency mock-javamail dependency and my project's bundle had identical BSNs

Could you elaborate on this sentence a bit more?

  • My project was (eg) org.myproject.
  • My project had Bundle Symbolic Name of org.myproject (standard Bndtools convention).
  • My workspace repository consequently had a bundle with BSN org.myproject.
  • My project had the mock-javamail artifact from the Jenkins repo on the build path, which was stored in my local .m2 directory in the usual place. It was not a bundle (didn't have a Bundle-SymbolicName header).
  • Somehow, the build added metadata from org.myproject got added to the mock-javamail artifact. This included setting the Bundle-SymbolicName header to org.myproject.
  • Consequently, Bndtools re-classified the mock-javamail artifact in the Jenkins repo from being a plain (non-bundle) artifact to being a bundle with BSN org.myproject.
  • Thus there were now two bundles in my workspace with BSN org.myproject:
    • The bundle generated in org.myproject/generated/org.myproject.jar (in the Workspace repo).
    • The Maven artifact in my .m2 directory (in the Jenkins repo).

Does that adequately explain it?

kriegfrj avatar Apr 02 '25 06:04 kriegfrj

Not that I have a clue, but I saw a setting aQute.bnd.repository.maven.provider.Configuration.noupdateOnRelease() which at least sounds related. https://bnd.bndtools.org/plugins/maven.html#plugin-configuration

If set to truthy then this repository will not update the index when a non-snapshot artifact is released.

chrisrueger avatar Apr 02 '25 15:04 chrisrueger

Not that I have a clue, but I saw a setting aQute.bnd.repository.maven.provider.Configuration.noupdateOnRelease() which at least sounds related. https://bnd.bndtools.org/plugins/maven.html#plugin-configuration

If set to truthy then this repository will not update the index when a non-snapshot artifact is released.

A complicating factor here is that there are several MvnBndRepositories in my workspace, and any of them could update the .m2 directory (in particular my Local repository, which is used as the deployment repo to deploy built bundles). This is a pretty normal setup.

So even if this flag was honoured for the Jenkins repo, a bug in MvnBndRepository could (eg) cause the Local repo to overwrite the same artifact in the .m2 cache.

kriegfrj avatar Apr 03 '25 01:04 kriegfrj

Another PR came to mind where the order of things was changed. https://github.com/bndtools/bnd/pull/6421/files

One thought / theory: Since you mentioned -includeresource: @${repo;org.jvnet.mock-javamail:mock-javamail;2.2.0}

Could it be that MANIFEST.MF information of org.jvnet.mock-javamail:mock-javamail made it into the MANIFEST of your project's JAR, so that suddenly your project's JAR looks like org.jvnet.mock-javamail:mock-javamail at some point in time (for a short moment), so which falsely leads to overwriting behavior?

Something like this maybe?

chrisrueger avatar Apr 04 '25 08:04 chrisrueger

Could it be that MANIFEST.MF information of org.jvnet.mock-javamail:mock-javamail made it into the MANIFEST of your project's JAR, so that suddenly your project's JAR looks like org.jvnet.mock-javamail:mock-javamail at some point in time (for a short moment), so which falsely leads to overwriting behavior?

Something like this maybe?

Yes, I think that is likely - I suspected that the -includeresource had something to do with it, probably in combination with the other transient error caused by my series of rapid changes which probably interrupted (possibly more than once) a build-in-progress.

I'm curious, though, where Bnd got its information from as to where to write the target jar - this requires knowing the GAV for the Maven coordinate, and this is not usually obtainable from the manifest alone?

kriegfrj avatar Apr 08 '25 00:04 kriegfrj

Can we close it? I think it is hard to reproduce. @kriegfrj

chrisrueger avatar Jun 06 '25 15:06 chrisrueger

I have closed it - as you point out, this is difficult to reproduce. Something to be on the lookout for, and we can reopen if necessary.

kriegfrj avatar Aug 05 '25 06:08 kriegfrj