Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIEventTopic isn't working #33

Closed
nedtwigg opened this issue Dec 15, 2022 · 5 comments
Closed

UIEventTopic isn't working #33

nedtwigg opened this issue Dec 15, 2022 · 5 comments
Labels
bug Something isn't working solstice-osgi

Comments

@nedtwigg
Copy link
Collaborator

The UIEventTopic isn't working, and I'm not sure why. The easiest symptom to observe is that you can't drag-and-drop the tabs around. If you put a breakpoint on the constructor to org.eclipse.e4.ui.workbench.addons.dndaddon.DnDAddon you'll see that it is being created, but its method is never called

	@Inject
	@Optional
	void subscribeTopicWidget(@UIEventTopic(UIEvents.UIElement.TOPIC_WIDGET) Event event) {

These events are supposed to be created by org.eclipse.e4.ui.internal.di.UIEventObjectSupplier. If you put a breakpoint on its constructor, you'll see that it is never created. A very similar class org.eclipse.e4.core.di.internal.extensions.EventObjectSupplier is successfully created. Here they both are:

// gets instantiated and placed into the service registry
@Component(service = { ExtendedObjectSupplier.class, EventHandler.class }, property = {
		"dependency.injection.annotation=org.eclipse.e4.core.di.extensions.EventTopic",
		"event.topics=" + IEclipseContext.TOPIC_DISPOSE }, immediate = true)
public class EventObjectSupplier extends ExtendedObjectSupplier implements EventHandler {}

// never gets instantiated and thus never placed into the service registry
@Component(service = { ExtendedObjectSupplier.class, EventHandler.class }, property = {
		"dependency.injection.annotation=org.eclipse.e4.ui.di.UIEventTopic",
		"event.topics=" + IEclipseContext.TOPIC_DISPOSE })
public class UIEventObjectSupplier extends EventObjectSupplier {

I can put breakpoints on the OSGi parsing to see that the UIEventObjectSupplier is being parsed. The problem is that EventObjectSupplier has immediate = true but UIEventObjectSupplier does not. That is why EventObjectSupplier is in the service registry but UIEventObjectSupplier is not.

A hack would be to force a UIEventObjectSupplier to get created and placed into the service registry, but there must be some deeper issue which is causing this...

The easiest way to debug this is with IdeMainTest, because all of the eclipse jars are just part of the regular classpath in an IDE.

public class IdeMainTest {
public static void main(String[] args) throws InvalidSyntaxException {

@nedtwigg nedtwigg added bug Something isn't working help wanted Extra attention is needed solstice-osgi labels Dec 15, 2022
@laeubi
Copy link

laeubi commented Dec 16, 2022

It seem soclstice do not handle service event correctly. DS works the way that it watches for events that a service is required and then triggers activation.

Beside that, if you don't want to reimplement OSGi just for the sake of a single classloader, you should take a look at https://docs.osgi.org/specification/osgi.core/8.0.0/framework.connect.html it will allow you to start a real OSGi framework and connect bundles with a custom classloader to them ...

@tjwatson
Copy link

Beside that, if you don't want to reimplement OSGi just for the sake of a single classloader, you should take a look at https://docs.osgi.org/specification/osgi.core/8.0.0/framework.connect.html it will allow you to start a real OSGi framework and connect bundles with a custom classloader to them ...

There is already an implementation that uses connect to provide integration with single class loader, native, or JPMS:

https://github.com/apache/felix-atomos

If you are looking to use a single classloader with existing JARs (that happen to be OSGi bundles), I suspect using something like Atomos will get you very far without having to re-implement "just enough" to get you running.

@nedtwigg
Copy link
Collaborator Author

Thanks very much for the Atomos link, maybe that solves our problem or at least helps us debug what we're doing incorrectly.

We've got lots of OSGi DS services that are starting correctly (EventObjectSupplier for example), so I don't think we're super far away from implementing enough of the spec for Eclipse to run correctly.

  • org.eclipse.osgi - 55 kLOC across 454 files
  • org.apache.felix.atomos - 4kLOC across 26 files
  • solstice (not counting p2) - 3kLOC across 24 files
  • solstice (p2 stuff) - 2kLOC across 18 files

In some ways solstice is already more complex than atomos, in that they both need org.eclipse.osgi, and solstice has a bunch of code that duplicates what org.eclipse.osgi is doing.

But taking something powerful (org.eclipse.osgi) and wrapping it with something simple (atomos) is different than something which is "just" simple (solstice, hopefully). That's our rationale for attempting this, we'll see where it goes :)

@nedtwigg nedtwigg mentioned this issue Dec 16, 2022
@nedtwigg nedtwigg removed the help wanted Extra attention is needed label Jan 5, 2023
@nedtwigg
Copy link
Collaborator Author

nedtwigg commented Jan 5, 2023

Thanks very much to @tjwatson for helping us integrate Atomos in #36. Single-classloader Atomos+Equinox is now the default OSGi implementation for EquoIDE. You can opt-out of Atomos+Equinox with

  • gradle plugin: ./gradlew equoIde --dont-use-atomos
  • maven plugin: mvn equo-ide:launch -DuseAtomos=false

in which case you'll be stuck on this bug again. We plan to come back and fix this someday, and it's quite a bit easier to do now that we can easily compare Solstice vs Atomos in the debugger. But this bug is no longer on the critical path towards getting our build plugins to 1.0, so this issue is shelved for now.

@nedtwigg
Copy link
Collaborator Author

nedtwigg commented Feb 8, 2023

The root problem turned out to be that when the starting state of our system was all bundles at state = INSTALLED. Then, one bundle at a time based on imports and exports, each bundle was activated, which involved sending events and moving state to RESOLVED and then STARTING and finally ACTIVE.

The fix is that on startup we bring every lazy bundle all the way to STARTING and the non-lazy bundles to RESOLVED.

for (var b : bundles) {
notifyBundleListeners(BundleEvent.INSTALLED, b);
b.state = Bundle.INSTALLED;
}
for (var b : bundles) {
notifyBundleListeners(BundleEvent.RESOLVED, b);
b.state = Bundle.RESOLVED;
}
for (var b : bundles) {
if (b.manifest.lazy) {
notifyBundleListeners(BundleEvent.LAZY_ACTIVATION, b);
b.state = Bundle.STARTING;
}
}

Badaboom, UIEventTopic comes to life!

@nedtwigg nedtwigg closed this as completed Feb 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working solstice-osgi
Projects
None yet
Development

No branches or pull requests

3 participants