Use SWT in Eclipse in a Java 15 modular setup - java

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:

Related

Not finding automatic modules when compiling Java Application

I have a large multi module (100s) Java project and have been experimenting with adopting java module support. This is using Java 17 (temurin), gradle 7.6, and IntelliJ 2022.3.
I have hit a couple of stubborn errors with java modules where the module cannot be found.
I have one project which has some java code that uses plexus ie:
import org.codehaus.plexus.util.Base64;
...
byte[] encodedAuthorizationString = Base64.encodeBase64(authorizationString.getBytes(StandardCharsets.US_ASCII));
It has a gradle dependency
implementation 'org.codehaus.plexus:plexus-utils'
This has a version constraint in our main build.gradle (just salient lines included):
plexusVersion = '3.5.0'
implementation("org.codehaus.plexus:plexus-utils:${plexusVersion}")
Prior to adding module support this is working fine.
Now, with a module-info.java:
module egeria.open.metadata.implementation.adapters.open.connectors.rest.client.connectors.spring.rest.client.connector.main {
requires egeria.open.metadata.implementation.adapters.authentication.plugins.http.helper.main;
requires egeria.open.metadata.implementation.adapters.open.connectors.rest.client.connectors.rest.client.connectors.api.main;
//requires egeria.open.metadata.implementation.adapters.open.connectors.rest.client.connectors.rest.client.factory.main;
requires egeria.open.metadata.implementation.frameworks.open.connector.framework.main;
requires plexus.utils;
requires org.slf4j;
requires spring.core;
requires spring.web;
exports org.odpi.openmetadata.adapters.connectors.restclients.spring;
}
I am getting a compile error
Task ':open-metadata-implementation:adapters:open-connectors:rest-client-connectors:spring-rest-client-connector:compileJava' is not up-to-date because:
Task has failed previously.
The input changes require a full rebuild for incremental task ':open-metadata-implementation:adapters:open-connectors:rest-client-connectors:spring-rest-client-connector:compileJava'.
Full recompilation is required because no incremental change information is available. This is usually caused by clean builds or changing compiler arguments.
Compiling with toolchain '/Library/Java/JavaVirtualMachines/temurin-19.jdk/Contents/Home'.
Compiling with JDK Java compiler API.
/Users/jonesn/IdeaProjects/egeria/v4/open-metadata-implementation/adapters/open-connectors/rest-client-connectors/spring-rest-client-connector/src/main/java/module-info.java:6: error: module not found: plexus.utils
requires plexus.utils;
^
1 error
This is despite the fact, that having downloaded the jar file, the automatic module name looks to be what I am using ie:
jar --file=/Users/jonesn/Downloads/plexus-utils-3.5.0.jar --describe-module
No module descriptor found. Derived automatic module.
plexus.utils#3.5.0 automatic
requires java.base mandated
contains org.codehaus.plexus.util
contains org.codehaus.plexus.util.cli
contains org.codehaus.plexus.util.cli.shell
contains org.codehaus.plexus.util.dag
contains org.codehaus.plexus.util.introspection
contains org.codehaus.plexus.util.io
contains org.codehaus.plexus.util.reflection
contains org.codehaus.plexus.util.xml
contains org.codehaus.plexus.util.xml.pull
I am seeing the same error with kafka-clients
For most other code, including those libraries without full module support, all is good....
tried various compilers, such as openjdk 17 & temurin 19
built at cli & within IntelliJ
I was expecting this module to resolve ok
I have also reviewed Java 9 automatic modules not found but note that other automatic modules (including org.slf4j) are working just fine
I should add that I could refactor this code to use java.util.Base64 (probably makes sense)... but I'm still confused as to why the module error, which I also see in another project with 'kafka.clients'

Compiling application with Tika with Java 13 - problems loading modules

I'm trying to migrate a Java application that uses Tika from OracleJDK 1.8 to OPenJDK 13.
My IDE is Eclipse.
I have created the file module-info.java to indicate the required modules for my application.
In order to be able to use Tika classes such as AbstractParser, Detector, etc., I have added requires org.apache.tika.core; in module-info.java.
My code also uses the class org.apache.tika.parser.pdf.PDFParserConfig to extract embedded images:
PDFParserConfig pdfConfig = new PDFParserConfig();
pdfConfig.setExtractInlineImages(true);
context.set(PDFParserConfig.class, pdfConfig);'
I get the compilation error:
PDFParserConfig cannot be resolved to a type
Eclipse suggests to add requires org.apache.tika.parsers; to module-info.java: Eclipse suggestion screenshot.
When I add this module requirement to module-info.java, the application compiles properly.
That is, at this stage we have included in module-info.java:
module myapp {
/** others ... */
requires org.apache.tika.core;
requires org.apache.tika.parsers;
}
However, when trying to execute the compiled application, we get the error:
Error occurred during initialization of boot layer
java.lang.module.FindException: Unable to derive module descriptor for C:\Users\Admin\.m2\repository\org\apache\tika\tika-parsers\1.24\tika-parsers-1.24.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class org.apache.tika.parser.onenote.OneNoteParser not in module
Inspecting the project Libraries in Eclipse, I can see that tika-core and tika-parsers (v1.24) are both modular: Eclipse Java Build Path
In conclusion: If I don't add org.apache.tika.parsers as a required module, the application won't compile, and if I add it I get the runtime error saying org.apache.tika.parser.onenote.OneNoteParser is not in the module.
I have inspected the JAR files for these packages to see the dependencies they have. The core packages seems to be right:
$ jar --file=tika-core-1.24.jar --describe-module
No module descriptor found. Derived automatic module.
org.apache.tika.core#1.24 automatic
requires java.base mandated
contains org.apache.tika
contains org.apache.tika.concurrent
contains org.apache.tika.config
contains org.apache.tika.detect
contains org.apache.tika.embedder
contains org.apache.tika.exception
contains org.apache.tika.extractor
contains org.apache.tika.fork
contains org.apache.tika.io
contains org.apache.tika.language
contains org.apache.tika.language.detect
contains org.apache.tika.language.translate
contains org.apache.tika.metadata
contains org.apache.tika.mime
contains org.apache.tika.parser
contains org.apache.tika.parser.digest
contains org.apache.tika.parser.external
contains org.apache.tika.sax
contains org.apache.tika.sax.xpath
contains org.apache.tika.utils
...but the 'parsers' jar gives an error:
$ jar --file=tika-parsers-1.24.jar --describe-module
Unable to derive module descriptor for: tika-parsers-1.24.jar
Provider class org.apache.tika.parser.onenote.OneNoteParser not in module
Does this mean the jar package for parsers is not well formed?
Is there any workaround for this?
Thank you.
EDIT:
If I try with version 1.24.1, I get the execution error:
Error occurred during initialization of boot layer
java.lang.module.FindException: Unable to derive module descriptor for C:\Users\Admin\.m2\repository\org\apache\tika\tika-parsers\1.24.1\tika-parsers-1.24.1.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class org.apache.tika.parser.external.CompositeExternalParser not in module
That is: the failing class is CompositeExternalParser instead of OneNoreParser.
Inspecting META-INF/services/org.apache.tika.parser.Parser of tika-parsers-1.42.1.jarI can see the entryorg.apache.tika.parser.external.CompositeExternalParser` but the package does not contain this class.
So, it seems to be an error in this META-INF file. Id this due to an error when compiling the package and submitting it to Maven Central?
I've found a JIRA issue, TIKA-2929, where they say "Apache Tika needs to be on the Java Classpath, not the module path". I've tried this, but, as explained before, I get a compilation error if I don't add it to the module path and set requires org.apache.tika.parsers;.
This is a hard puzzle...
Ran into the same issues.
Also found the faulty entries in
org.apache.tika.parser.Parser (and also org.apache.tika.parser.Detector) in META-INF/services/
A quick fix is to ...
Unpack those files
delete the lines that seem to reference non existing classes
pack them back into the jar
My project compiled after that.
For sure no longterm solution, but since even older versions i tried ran into that problem, it might help out some people.

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?

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.

Confused with classloading in OSGI

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

Categories

Resources