Compiling application with Tika with Java 13 - problems loading modules - java

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.

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'

Gradle: program type already present

I am trying to start working with libaums project ( https://github.com/magnusja/libaums ).
I wrote a class Log which mirrors the methods of android.util.Log, yet writes everything into a file (since I cannot get access to debug output stream on android). I was unable to understand how to build a package out of the module I wrote and include it as a local dependency into the libaums project ( Gradle compilation: package not found ), so I decided just to import Log.java (which is a com.iglogger package that implements Log class) in both of libaums projects (app and the actual libaums library). That in turn created a problem on the stage of merging dex files - so that app project depends on both Log class and libaums and yet libaums uses Log class too.
13684:09:44:38.705 [ERROR] [com.android.build.gradle.internal.tasks.DexMergingTaskDelegate] java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
13861:Caused by: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
13649:09:44:38.698 [ERROR] [org.gradle.api.Project] D8: Program type already present: com iglogger.Log
13685:Program type already present: com.iglogger.Log
13862:Program type already present: com.iglogger.Log
13871:Program type already present: com.iglogger.Log
After some research, the solution seems to be that I have to exclude the dependency on Log.java (i.e. com.iglogger.Log) while importing libaums into app project . But how exactly I suppose to do that in my case? It seems that I have declare a dependency on Log.java in the libaums project, so that I will be able to exclude it later on.. Right? If so, then how?
So the problem resolved with a removal of the files (com/iglogger) from the app project that depends on lib project.
I.e. the import statement in java seems to include not only declaration of packages to use, but, optionally, the objects of the packages themselves.

Unable to derive module descriptor: Provider {class X} not in module

I am getting this error message when I try to compile my new modularized Java 11 application:
Error occurred during initialization of boot layer
java.lang.module.FindException: Unable to derive module descriptor for C:\Users\inter\.m2\repository\xalan\xalan\2.7.2\xalan-2.7.2.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class org.apache.bsf.BSFManager not in module
This appears to be an issue from a dependency of a dependency. I can't even find which module is pulling it in so I can update it.
I am using openjdk 11.0.2, IntelliJ 2018.3.4, Maven
Any advice how I can troubleshoot or fix this? I have found very little documentation on this issue.
Xalan
I had a look at their bug tracker following their index page and wasn't able to find this reported and not sure how actively is the library being maintained either.
General Explanation
Just to explain what has caused the issue in your code, I would share a screenshot and then try to add details around it.
So within the JAR that for version 2.7.2, there are service declarations (META-INF/services) which include org.apache.xalan.extensions.bsf.BSFManager as one of them. The service file here has to indicate the Provider thereby for itself and the class is supposed to be present on the modulepath to be resolved for reliable configuration of modules.
In this case for the module xalan(automatic module), the service listed doesn't have the provider class packaged within the dependency itself. (See the package org.apache, it doesn't further have package bsf and the class BSFManager thereby. Hence the exception as you get.
Short term hack
One of the tweaks to get that resolved would be to get update the library jar (patch it) and get rid of the service file if you're not using it. Or to add the provider copied from the corresponding artifact.
If you don't directly depend on this artifact or its parent dependencies, you can let those remain on the --classpath and get resolved as an unnamed module for your application.
Long term solve
An ideal way would be to report this to the maintainers and getting it resolved. It depends though on how actively are they maintaining it e.g. the last release for xalan was almost 5 years back, might just want to look for an actively participated alternative in my opinion.
I tried to install update for TestNG in eclipse:
"Help -> Check for updates -> deselect all and select TestNG check box. Then
install latest version i installed the version which starts with 7.2.0.
It fixed the issue for me.

Grails 2.1.1 - How to develop a plugin with an AstTransformer?

I want to replace the auto injected log object, which is of type org.apache.commons.logging.Log with an object of type org.slf4j.Logger, so that I can use it properly with Logback.
Therefore I need to create a ...Transformer class (written in Java) - that's what I got from Graeme Rocher over at the "grails-user" mailing list. I'm also aware that I have to pack this ...Transformer class within a plugin and make it a *.jar archive which I can load within the lib/ folder of the plugin. But I guess I'm doing something wrong here as I have the class, along with a META-INF folder which contains the MANIFEST.MF file as well as another folder services which holds the following file org.codehaus.groovy.transform.ASTTransformation which holds just one String: the canonical name of the ...Transformer class.
Now, if I try to do a grails clean everything is fine, BUT if I try to run grails package-plugin the console comes up with a java.lang.ClassNotFoundException.
Clipping from Stacktrace:
| Packaging Grails application...
| Error Fatal error during compilation org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Could not instantiate global transform class my.package.ast.LoggingTransformation specified at jar:file:/C:/Source/MyGrailsAST/lib/replace-logging-logback-ast.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.ClassNotFoundException: my.package.ast.LoggingTransformation
1 error
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Could not instantiate global transform class my.package.ast.LoggingTransformation specified at jar:file:/C:/Source/MyGrailsAST/lib/replace-logging-logback-ast.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.ClassNotFoundException: my.package.ast.LoggingTransformation
Does anybody have some experience with Grails plugins which handle with AstTransformer and could give me some advice on this? Is there a good tutorial out there which I haven't seen so far?
Please let me know ;)
so, after some research, browsing and finally asking at the Grails Mailing List (see the mailing list archives at: http://grails.1312388.n4.nabble.com/Grails-user-f1312389.html I found a solution.
my goal was to create a Globals ASTTransformation, to inject a org.slf4j.Logger object instead of the usual org.apache.commons.logging.Log object into every Artefact class without annotation.
so, here are the steps:
I created Java class similar to https://github.com/grails/grails-core/blob/master/grails-logging/src/main/groovy/org/codehaus/groovy/grails/compiler/logging/LoggingTransformer.java but with my own implementation of the org.slf4j.Logger object. It is crucial that you place the Java.class under the following package: org.codehaus.groovy.grails.compiler as
Grails scans for classes that are annotated with #AstTransformer in this package. (Graeme Rocher)
and pack it into a JAR along with its MANIFEST.MF file within the META-INF/ folder. A META-INF/services directory with all its stuff is not needed as Graeme Rocher stated:
You do not need the META-INF/services stuff and I would remove it as it is probably complicating matters.
So, I guess this statement was more related to my specific problem as I only have one #AstTransformer class within my plugin, but that's just a guess. And I haven't searched for further informations on this topic. Maybe some other developer here who needs this could do some research and share his solution within this thread...
The JAR should be imported to the plugin and placed under the lib/ directory. After this you should be able to do grails clean, grails compile and grails package-plugin.
If you want to replace the log implementation, as I did, you should exclude the grails-logging and grails-plugin-log4j JARs from your designated project's classpath. This is done in the BuildConfig.groovy file:
inherits("global") {
excludes "grails-plugin-log4j", "grails-logging"
}
Now install your plugin grails install-plugin \path\to\plugin.zip and everthing should work as expected.
Hope this helps...

Debugging java file compiling (using gwt)

I was asked in a precedent question to be more precise about my compilation error message. Here's the fact : I know nothing about GWT and Java. Following the docs, I tried to compile Java files from a web project that had been precedently developed using GWT. So, to test and understand how all this work, I took the java folder (that had been precedently compiled with an appropriate tool)
into src folder of a web app project in my ide Eclipse
When running the compiler using the command GWT Compile, I had this message error :
Compiling module java.org.primagora
Validating newly compiled units
Ignored 5 units with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
Finding entry point classes
[ERROR] Unable to find type 'org.client.primagoraEntryPoint'
[ERROR] Hint: Check that the type name 'org.client.primagoraEntryPoint' is really what you meant
[ERROR] Hint: Check that your classpath includes all required source roots
When I look at the error on the file, for example java.org.client.primagoraEntryPoint, I find an error when it is declared "package org.client" at the very beginning of the file. There seem to be an error path. I thought the java folder I took would be correctly implemented in Eclipse.
Is that clearly a file path problem ? How should I debugg it ? (I reallly know nothing about gwt, java , eclipse)
Best,
Newben
Where is your GWT module file (i.e. a file that ends in .gwt.xml), and what are its contents? The package you list for your entrypoint is org.client, and the full name is org.client.primagoraEntryPoint, suggesting that there is a file in org/client/primagoraEntryPoint.java. By default, module files include the client package relative to them as source, so if the file is in the wrong location, this won't work correctly.
Based on this, your module file should be in the org package:
src/
org/
SampleModule.gwt.xml
client/
primagoraEntryPoint.java
From the very beginning of your error, you list java.org.primagora as the module:
Compiling module java.org.primagora
This suggests the following structure:
src/
org/
client/
primagoraEntryPoint.java
java/
org/
primagora.gwt.xml
This doesn't make sense, since GWT is now looking for a java.org.client package instead of a org.client package. Try using the package setup mentioned earlier here.
A better option might be to pick an existing working project, like what the GWT plugin for Eclipse will create, or one of the samples in the GWT download.

Categories

Resources