The reason is that we compile against Eclipse-4.25/org.eclipse.jdt.ui-3.27.0.v20220824-0714.jar. In this version the package org.eclipse.jdt.internal.corext.refactoring.rename is present.
However, when we run we are linked to org.eclipse.jdt.core.manipulation_1.16.200.v20220824-0551 for this package. Both the bundle org.eclipse.jdt.ui and org.eclipse.jdt.core.manipulation export the same package org.eclipse.jdt.internal.corext.refactoring.rename. However, they have different contents.
They have been happily inventing some additional modularity stuff on top of OSGi. When you look at the export of org.eclipse.jdt.core.manipulation, you see:
There seems to be some Eclipse C++‘s and JPMS’ friend function envy? This seems a backdoor to get split packages? Tom Watson can probably tells us how this works.
In the OSGi, we spend countless hours discussing friend bundles. We decided after very ample deliberations to not do this. The key concept in OSGi is service based design, where your service has a clear distinction between API and implementation, modeled through a set of interfaces in a package. Libraries, bundles where API + implementation is together, is ok but it is never ok to splat a library over multiple bundles. The whole idea of modules is that you keep your implementations in your pants. Any implementation wandering in the public space is wrong, it is like you cannot be a little bit pregnant. You play by the rules, you get the benefits. Do this nice looking hack, you just pay a shitload of money for OSGi + Java complexity and all benefits just just dumped while adding another shitload of complexity on your users.
The thing is modularity is hard. Modularity in Java is surprisingly hard.
It is a tad frustrating, been here for 20 years, and it feels like a Sisyphus task. Maybe it is time to shut up
This turned out to be org.eclipse.osgi.internal.loader.EquinoxClassLoader@3f5dfe69[org.eclipse.jdt.ui:3.27.0.v20220824-0714(id=190)]
Then I set a break point on the Class Not Found Exception. This broke here:
Using he Debug Shell again on the Bundle Loader, I looked at this.importedSources.get("org.eclipse.jdt.internal.corext.refactoring.rename") which is the import table (I guessed). This was org.eclipse.jdt.internal.corext.refactoring.rename -> [org.eclipse.jdt.core.manipulation_1.16.200.v20220824-0551]
I wonder is there any (theoretical) chance or way to make this visible in bndtools / bnd?
Maybe a gogo shell command? Which part of the tooling would be able to get this? Only the running framework right?
Problem is that this problem only occurs when you have no idea what you’re doing. If you get this problem, it is highly likely there are myriad of class loader and timing problems hidden in the code. Of course they will tell you: “but it works?” Yup, most of the time.
Agree. But since we had this problem specifically in bndtools I just thought if there was a way that tool itself could help you analyse this problem. You are probably the only person on earth able to analyse and find this problem Since bndtools is supposed to support you in writing good OSGi programs, I think it would be great if the tool could slap this kind of issue in your face (a warning, red light…something)
From a marketing perspective it is this sentence on the bndtools website which crossed my mind:
You are probably the only person on earth able to analyse and find this problem
No, BJ is Yoda here And Tom Watson is close.
And this problem here seems to be “hard to debug”.
Well, bnd goes out of its and and more to prevent these problems. In this case, it is a runtime problem in Eclipse. It would be interesting to hear Tom Watson about the x-friend attribute. Note that this seems self inflicted pain. We might run into it because we use package imports and not Require-Bundle.
I do not think Bndtools should try to alleviate these problems, only prevent them!
I just did a search for other uses where we use .internal packages. Do you think those are also potential candidates for future headaches / breaking stuff?
I’ve always seen the internal package as ‘plausible deniability’. I did some of the JUnit OSGi stuff and it was impossible as far as I could see to extend or even use the UI without touching internal classes.
I really don’t know. I haven’t got a lot of experience with Eclipse. Neil Bartlett set it all up and BJ maintained it, I just wrestled and muddled in that environment.
Are there alternatives for all these packages? Some of the class names suggest pretty general functionality.