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

fireplace-swing-animation cannot be used in OSGI due to a classloading error #109

Closed
bric3 opened this issue Sep 8, 2022 · 1 comment
Closed
Labels

Comments

@bric3
Copy link
Owner

bric3 commented Sep 8, 2022

It seems in OSGI, a code that only uses a public interface, fails to to use the implementer of this interface if it's a package visible class.
(Could it be related to the fact that it's a split package (as each loader have their own classloader)?)

graph LR
    fireplace-swing-animation[swing-animation<br>package: .fireplace.flamegraph] ==>|Require-Bundle: fireplace-swing| fireplace-swing[fireplace-swing<br>package: .fireplace.flamegraph]
    fireplace-swing-animation -->|Require-Bundle: radiance-animation| radiance-anim(radiance-animation<br>non-osgi, patched via p2-maven-plugin)

    ZoomAnimation --> ZoomableComponent
    subgraph fireplace-swing-module[fireplace-swing]
        subgraph FlamegraphView[public class FlamegraphView]
            FlamegraphCanvas["(package visible) class FlamegraphCanvas"] --> ZoomableComponent(public interface ZoomableComponent)
        end
    end
    subgraph fireplace-swing-animation-module[fireplace-swing-animation]
    ZoomAnimation[public class ZoomAnimation]
    end
Loading
Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: failed to access class io.github.bric3.fireplace.flamegraph.FlamegraphView$FlamegraphCanvas from class io.github.bric3.fireplace.flamegraph.ZoomAnimation (io.github.bric3.fireplace.flamegraph.FlamegraphView$FlamegraphCanvas is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @6e466fdf; io.github.bric3.fireplace.flamegraph.ZoomAnimation is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @3c023897)
	at io.github.bric3.fireplace.flamegraph.ZoomAnimation.zoom(ZoomAnimation.java:64)
	at io.github.bric3.fireplace.flamegraph.FlamegraphView.zoom(FlamegraphView.java:658)
	at io.github.bric3.fireplace.flamegraph.FlamegraphView$FlamegraphScrollPaneMouseInputListener.lambda$mouseClicked$1(FlamegraphView.java:766)
	at java.base/java.util.Optional.ifPresent(Optional.java:183)
	at io.github.bric3.fireplace.flamegraph.FlamegraphView$FlamegraphScrollPaneMouseInputListener.mouseClicked(FlamegraphView.java:766)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6638)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
...

See EquinoxClassLoader


Note, as radiance is not an osgi bundle the p2-maven-plugin is instructed to patch the jar

<artifact>
	<id>io.github.bric3.fireplace:fireplace-swing-animation:${fireplace.version}</id>
	<source>true</source>
	<override>true</override>
	<instructions>
		<Require-Bundle>fireplace-swing,radiance-animation</Require-Bundle>
	</instructions>
</artifact>
<!-- Non OSGI dependency of fireplace-swing-animation -->
<artifact>
	<id>org.pushing-pixels:radiance-animation:${radiance.version}</id>
	<source>true</source>
	<override>true</override>
	<instructions>
		<Bundle-Name>radiance-animation</Bundle-Name>
		<Bundle-SymbolicName>radiance-animation</Bundle-SymbolicName>
	</instructions>
</artifact>

Related to openjdk/jmc#408

@bric3 bric3 added the osgi label Sep 8, 2022
@bric3
Copy link
Owner Author

bric3 commented Sep 8, 2022

Some interesting reading OSGi demystified, Split Packages – An OSGi nightmare

In particular there's a split package section

Bold are mine

A split package is the situation where classes from the same package are provided by more than one JAR. In the normal Java world where you are dealing with a single hierarchical class loader, there is no issue. Even when accessing package-private classes, everything works quite well. However, if you bring this concept into the OSGi world, you are begging for trouble. In OSGi, each OSGi bundle has its own class loader. If you put two parts of a package in different OSGi bundles, those classes end up on different class loaders and are considered incompatible because Java uses the class loader/package/class combination as the unique identifier. Split packages in OSGi often result in a java.lang.IllegalAccessError exception at runtime.

This look like the encountered issue (IAE). There's even a suggestion about bundle fragments.

In OSGi, a package is considered an atomic unit so it should be loaded by the same class loader to ensure consistency. If you really need to split packages and re-factoring isn't an option, a workaround is to make one of the OSGi bundles an OSGi bundle fragment instead. A fragment always lives within a host OSGi bundle, so applying this fragment always lives within a host OSGi bundle and applying this technique ensures that both are loaded by the same class loader.


Related SO question for fastutil

@bric3 bric3 closed this as completed in 3f64985 Sep 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant