Confused with classloading in OSGI - java

I have an RCP project in which I ran into problems.
I have an OSGI jar lets say jar-A which imports some packages from another osgi jar lets say jar-B. Now I have one more osgi jar-C that has the same package structure as jar-A but different classes in it.
I have a plugin say "plugin-A" that has both jar-A and jar-B in its build path and as a runtime dependency. Now plugin-A exports the jar-A and jar-B's packages.
I have one more "plugin-B" that has "jar-C" in its build path and as a runtime dependency. Now plugin-B has plugin-A as a required bundle. So technically it should be able to access "jar-A" and "jar-B's packages right?
Now plugin-B has a class that imports packages from jar-A and jar-C's classes. It is recognizing jar-C's classes fine since it is in the build path, but it is not recognizing jar-A's classes. It says "The type of class some X cannot be resolved. It is indirectly referenced from required .class files", where the some X class is in jar-A. Shouldn't this X class be recognized from the required bundle plugin-A which exports this class?
When I put this jar-A in plugin-B's bundle path I am not getting this issue anymore.

I'm not sure I follow all that, but only packages that are listed in the Export-Package entry in the plugin's MANIFEST.MF file are available to other plugins.
In the MANIFEST.MF editor specify these on the 'Runtime' tab in the 'Exported Packages' section.
An example Export-Package section from one of my plugins:
Export-Package: greg.music.core.common,
greg.music.core.databinding,
greg.music.core.e4util,
greg.music.core.editor,
greg.music.core.preferences,
greg.music.core.progress,
greg.music.core.services,
greg.music.core.showin,
greg.music.core.util,
greg.music.core.views,
greg.music.core.xml

Related

Use SWT in Eclipse in a Java 15 modular setup

I'm just trying to get the basic Hello World (project Trial0) application running using:
Eclipse Version: 2020-12 (4.18.0)
With SWT 4.18 (Linux, GTK)
with the Java Compiler set to 15
Following the (kinda ancient, it's about JDK 1.4 and SWT 3.1) description in Developing SWT applications using Eclipse, I have imported the SWT project into Eclipse:
Go to https://download.eclipse.org/eclipse/downloads/index.html#Stable_Builds
Click on "4.18" to reach https://download.eclipse.org/eclipse/downloads/drops4/R-4.18-202012021800/
Scroll down until you reach "SWT Binary and Source" and download the zip
swt-4.18-gtk-linux-x86_64.zip.
The zip includes 'swt.jar' (which includes the '.so' files). Launch Eclipse's "File > Import > General > Existing Projects into Workspace", the select the above zip as "Archive File"
I immediately hit a modularization/Jigsaw snag in a project that uses the imported SWT project. The compiler apparently is not allowed to see the SWT classes, which are not modularized:
"The package org.eclipse.swt.widgets is not accessible"
In this code:
package trial;
import org.eclipse.swt.widgets.*; // "The package org.eclipse.swt.widgets is not accessible"
public class MyApp {
}
Here is the project:
Note the module-info.java file on the importing project. It contains:
module trial0 {
requires java.desktop;
}
The swt.jar indeed does not advertise modules:
$ jar --file=swt.jar --describe-module
No module descriptor found. Derived automatic module.
swt automatic
requires java.base mandated
contains org.eclipse.swt
contains org.eclipse.swt.accessibility
contains org.eclipse.swt.awt
contains org.eclipse.swt.browser
contains org.eclipse.swt.custom
contains org.eclipse.swt.dnd
contains org.eclipse.swt.events
contains org.eclipse.swt.graphics
contains org.eclipse.swt.internal
contains org.eclipse.swt.internal.accessibility.gtk
contains org.eclipse.swt.internal.cairo
contains org.eclipse.swt.internal.dnd.gtk
contains org.eclipse.swt.internal.gtk
contains org.eclipse.swt.internal.image
contains org.eclipse.swt.internal.opengl.glx
contains org.eclipse.swt.internal.webkit
contains org.eclipse.swt.layout
contains org.eclipse.swt.opengl
contains org.eclipse.swt.printing
contains org.eclipse.swt.program
contains org.eclipse.swt.widgets
Do I need to add module-info.java files to the SWT jar? Is there another "canonical" way of pulling the SWT jar up into modularization-land?
As you could see based on the output describing the module from the jar file.
In your module-info.java file, you shall add the following directive:
requires swt;
This would provide you the access to the package org.eclipse.swt.widgets which the module swt(automatic module name) claims to
contains org.eclipse.swt.widgets
in its description itself.
The file module-info.java of the importing project now contains:
module trial0 {
requires java.desktop;
requires swt;
}
Eclipse attaches this warning to the line requires swt;:
Name of automatic module 'swt' is unstable, it is derived from the
module's file name.
That's ok.
The above may still not not work. In that case, verify the following:
The project org.eclipse.swt is on the importing project's Modulepath, instead of Classpath:
There needs to be an access rule on the imported module. The following access rules seems to work:
Note that there is nothing specific defined in the "Module Dependencies" for the importing project:

Maven test jar and Java 11 modules

How can we create a Maven test jar with Java 11 modules?
The only way I found is to add a module-info.java file to test/java and change the module name (e.g. append ".test"). Then provide the class in a separate package (e.g. append ".test") and export that package:
module my.module.test {
requires my.module;
exports my.module.test;
}
Otherwise the classes are not visible or I get split package issues.
But this isn't really the purpose of the test-jar goal and it limits access to "my.module".
What is the proper way to use test-jar with Java 11 modules? Or should it be avoided?

Making Maven and module-info work together

I have a project(Java 12) with several Maven dependencies, and now I'm trying to add module-info file like
module mymodule {
requires java.net.http;
}
But if I do this all Maven dependecies (in pom.xml) become invisible for code, and compiler throws errors like java: package org.openqa.selenium.safari is not visible
(package org.openqa.selenium.safari is declared in module selenium.safari.driver, but module mymodule does not read it)
Is it possible to make them work together?
The new module info ist not congruent with the information in the pom.xml. Robert wrote a good article about the differences of both systems:
https://www.sitepoint.com/maven-cannot-generate-module-declaration/

Cannot extend CDT CEditor: "The hierarchy of the type '' is inconsistent"

When trying to write a class that extends I get the error message:
The hierarchy of the type 'MYEditor' is inconsistent.
import org.eclipse.cdt.internal.ui.editor.CEditor;
public class MYEditor extends CEditor {
}
This answer says:
These errors happened because some interface/class in the hierarchy
cannot be resolved.
This indicates that eclipse cannot find a class in the hierarchy. But when I use the class in my plugin.xml, it works. I am using it like this:
<editor
class="org.eclipse.cdt.internal.ui.editor.CEditor"
contributorClass="org.eclipse.cdt.internal.ui.editor.CEditorActionContributor"
default="true"
filenames="*.grasp, *.c"
icon="icons/small.png"
id="de.blub.ide.myeditor"
name="My Editor">
</editor>
This works, but lacks a few features that I need for my plugin. That's why I want to use a class that inherits from CEditor.
This answer didn't work, to (remove and add JRE System Library).
I've also read that the jar file needs to be put in the Classpath section of the plugin.xml. But the "Add" and "New" Buttons don't provide a way to chose an external jar file. I can manually copy that jar file from "~/.p2/pool/plugins" into my projects lib folder, but that didn't help.
Plug-ins reference code in other plug-ins by including the other plug-in in their dependencies list. This is the Require-Bundle entry in the plug-in's MANIFEST.MF.
In the MANIFEST.MF/plugin.xml/build.properties editor you can set the dependencies in the 'Required Plug-ins' section on the 'Dependencies' page.
Do not copy plugin jars, do not put plugin jars in the Java Build Path.
But note that extending internal classes is against the Eclipse API Rules of Engagement. Internal classes may change without warning and may be different in older releases.
The CDT Plug-in Programmer's Guide covers the official APIs for Eclipse CDT.

Method getModule returning unnamed module for class in named module

I just started to have a look at the Java 9 module system and I was wondering whether it is possible for a class to know in which module it is located.
Therefor I created the following module
module de.test {
exports de.test.myexport;
}
and compiled a jar file that looks like
> jar --print-module-descriptor --file=Java9Test-1.0-SNAPSHOT.jar
de.test
requires mandated java.base
exports de.test.myexport
In package de.test, I have a class called Overview where I'm calling
Module module = Overview.class.getModule();
However, the returned module object is unnamed and has no ModuleDescriptor.
Am I using getModule() correctly here, or is there any other way to load the module of a class?
I'm using JDK 9 build 120 on OS X.
All JARs on the class path (with java --class-path ...) get bundled into the same so-called unnamed module, regardless of whether they are "a real module" or "just a JAR". When you ask a class from such a JAR for its module, you get the result you describe.
Try putting the JAR on the module path (with java --module-path ...) and Class::getModule should return what you expect.

Categories

Resources