Skip to content

FELIX-6864 Improve exception message for conflicting singleton - #565

Open
kwin wants to merge 1 commit into
apache:masterfrom
kwin:feature/FELIX-6864-improve-singleton-conflict-exception
Open

kwin wants to merge 1 commit into
apache:masterfrom
kwin:feature/FELIX-6864-improve-singleton-conflict-exception

Conversation

@kwin

@kwin kwin commented Oct 5, 2026

Copy link
Copy Markdown
Member

Emit conflicting bundle id and add countermeasure in case conflicting bundle is already uninstalled.

@paulrutter

Copy link
Copy Markdown
Contributor

@kwin can you sync with master? Then we can run ci again.

Emit conflicting bundle id and add countermeasure in case conflicting
bundle is already uninstalled.
@kwin
kwin force-pushed the feature/FELIX-6864-improve-singleton-conflict-exception branch from 6b82ac9 to 8865bc0 Compare October 15, 2026 12:26
@kwin

kwin commented Oct 15, 2026

Copy link
Copy Markdown
Member Author

@paulrutter Done, now TCK builds are successful as well.

@paulrutter

Copy link
Copy Markdown
Contributor

Alright, i'll try to take another look soon and hopefully we can take this along with next 8.0.0 release (JDK 25).

throw new ResolveException("Singleton conflict.", br, null);
BundleRevision conflictingRevision = findConflictingSingleton(br);
throw new ResolveException(
"Singleton conflict for Bundle-SymbolicName " + br.getSymbolicName()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message always says "Another bundle is already providing this singleton BSN", but findConflictingSingleton can return null, e.g. when br was not selected because a resolver hook whitelist filtered it out, or it lost to a higher version in the same resolve. The text then reads "...singleton BSN: ?.", which is wrong and misleading. Consider different wording for the null case.

String details = "[id=" + conflictingBundle.getBundleId() + "]";
if (conflictingBundle.getState() == Bundle.UNINSTALLED)
{
details += ". This bundle is already uninstalled. Call refreshPackages() to remove it from the framework.";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an uninstalled conflicting bundle this string already ends with a period, and the caller appends another one, so the message ends in "..". Also, refreshPackages() is the deprecated PackageAdmin API; FrameworkWiring.refreshBundles() is the current one.

return m_selectedSingletons.contains(br);
}

private synchronized BundleRevision findConflictingSingleton(BundleRevision br)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests cover the new message or helpers. The null, uninstalled and normal conflict branches are all unexercised, so a later change to the message format or to singleton selection could break them silently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants