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

Split packages between MigLayout Core and IdeUtil #103

Closed
ptziegler opened this issue Dec 8, 2023 · 13 comments · Fixed by #104
Closed

Split packages between MigLayout Core and IdeUtil #103

ptziegler opened this issue Dec 8, 2023 · 13 comments · Fixed by #104

Comments

@ptziegler
Copy link
Contributor

Both the IDEUtil class and the Core Miglayout classes are located in the net.miginfocom.layout package. This causes problems in Java 9 with regards to e.g. modules.

@tbee
Copy link
Collaborator

tbee commented Dec 8, 2023

Split packages problems I assume? But if you keep miglayout on the classpath, because it is not a module, then there should be no problems.

@ptziegler
Copy link
Contributor Author

Split packages problems I assume?

That's sadly the problem.

But if you keep miglayout on the classpath, because it is not a module, then there should be no problems.

For a normal Java project, that's true. But I probably should've mentioned that I use this jar in an OSGi environment...

To break down the actual problem:

We currently have a "fat" jar containing both com.miglayout.core and com.miglayout.ideutils. Ideally, I'd like to migrate to the official jars. But this fails with the following exception:

Caused by: java.lang.ClassNotFoundException: net.miginfocom.layout.UnitValue cannot be found by com.miglayout.ideutil_11.2.0
	at org.eclipse.osgi.internal.loader.BundleLoader.generateException(BundleLoader.java:540)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:535)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:415)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:167)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	... 43 more

This is because the manifest file of com.miglayout.ideutil is missing the Import-Package headers, which would tell OSGi that this jar imports packages from com.miglayout.core. My guess is that this is because both jars export the same packages, hence the split-package issue.

Note: Even if this header existed, it would still not be possible to ensure that those are satisfied by com.miglayout.core

As a workaround, it might be possible to simply add this dependency via the Require-Bundle header. But I have to test whether that actually works.

I think the clean solution would probably be to move the IDEUtil class to its own package. Though I assume that is undesirable because it would break API.

@ptziegler
Copy link
Contributor Author

As a workaround, it might be possible to simply add this dependency via the Require-Bundle header. But I have to test whether that actually works.

After a quick test, that solves the ClassNotFoundException. But it only causes the next batch of exceptions...

java.lang.IllegalAccessError: class net.miginfocom.layout.IDEUtil tried to access field net.miginfocom.layout.UnitValue.ZERO (net.miginfocom.layout.IDEUtil is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @61c3b31c; net.miginfocom.layout.UnitValue is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @7acc95a2)

UnitValue.ZERO is a package-private field which is accessed by IDEUtil. This only works if both classes are loaded by the same classloader... :(

@tbee
Copy link
Collaborator

tbee commented Dec 10, 2023

Okay. I cannot test in in OSGi environment, but renaming that package and adding line or two to the manifest is doable. Maybe you can test what works and make a PR? Or tell me what must change?

@ptziegler
Copy link
Contributor Author

Maybe you can test what works and make a PR?

That's the plan :) Though I fear that this might be a little bit more complicated than just adapting the manifest or moving some classes around.

From what I can tell, the IDEUtil class is primarily used to expose package-private fields and methods from the Core jar. Meaning that moving it to a different package brings its own problems.

I'll have to play around with it a little to hopefully come up with a good solution...

@DevCharly
Copy link
Contributor

From what I can tell, the IDEUtil class is primarily used to expose package-private fields and methods from the Core jar

I would suggest to simply move class IDEUtil to core and drop miglayout-ideutil.jar.

@ptziegler
Copy link
Contributor Author

I would suggest to simply move class IDEUtil to core and drop miglayout-ideutil.jar.

I'm slowly getting the impression that this really is the cleanest solution.

To briefly summarize the problem:

package private fields and methods can only be accessed if two conditions are met.

  • Both classes are in the same package
  • Both classes are loaded by the same classloader
    The latter is violated in OSGi, if the classes are located in separate bundles.

In other words, I need to find a way to load IDEUtil with the same classloader that is used by miglayout-core. There are options to do it with e.g. SPI or similar mechanisms but in the end, I'm not sure if this is really worth the effort.

@tbee
Copy link
Collaborator

tbee commented Dec 11, 2023

Fine with me. See if that works?

ptziegler added a commit to ptziegler/miglayout that referenced this issue Dec 11, 2023
The IDEUtil class is used to expose package-private functionality from
miglayout-core to external projects.
This mechanism fails in an OSGi environment, because the IDEUtil class
is loaded by a different classloader that is used to load classes it
tries to access.

To solve this problem, move IDEUtil to miglayout-core. Given that the
ideutil project is now empty, it is removed from the repository.

resolves mikaelgrev#103
@ptziegler
Copy link
Contributor Author

Fine with me. See if that works?

I've tested my changes locally and moving IDEUtil to miglayout-core seems to do the trick.

image

ptziegler added a commit to ptziegler/miglayout that referenced this issue Dec 11, 2023
The IDEUtil class is used to expose package-private functionality from
miglayout-core to external projects.
This mechanism fails in an OSGi environment, because the IDEUtil class
is loaded by a different classloader that is used to load classes it
tries to access.

To solve this problem, move IDEUtil to miglayout-core. Given that the
ideutil project is now empty, it is removed from the repository.

resolves mikaelgrev#103
ptziegler added a commit to ptziegler/miglayout that referenced this issue Dec 11, 2023
The IDEUtil class is used to expose package-private functionality from
miglayout-core to external projects.
This mechanism fails in an OSGi environment, because the IDEUtil class
is loaded by a different classloader that is used to load classes it
tries to access.

To solve this problem, move IDEUtil to miglayout-core. Given that the
ideutil project is now empty, it is removed from the repository.

resolves mikaelgrev#103
@tbee tbee closed this as completed in #104 Dec 11, 2023
@tbee
Copy link
Collaborator

tbee commented Dec 11, 2023

You forget a reference in demo.
I've released 11.3

@ptziegler
Copy link
Contributor Author

You forget a reference in demo.

My apologies. I've went through the project again, and I think there are other references that I missed as well. This should be fixed via #105

I've released 11.3

Awesome! Thank you both for your time. This really helps me out in getting rid of our embedded jars. :)

@tbee
Copy link
Collaborator

tbee commented Dec 12, 2023

No problem. Thanks for addressing the issue.

@mikaelgrev
Copy link
Owner

Sorry for being late to the discussion, but it all seem to the the right way forward. There were reasons back then for keeping them separated, I hope.., but I can't recollect any of them today.

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 a pull request may close this issue.

4 participants