Oracle JavaMail IMAP provider not compatible with Java 9? - jakarta-mail

I get a compile error from maven when building a project under Java 9 that uses the Oracle JavaMail IMAP provider:
... cannot access com.sun.mail.util.ReadableMime
[ERROR] class file for com.sun.mail.util.ReadableMime not found
(ReadableMime is an interface implemented by IMAPMessage)
It works under Java 8.
The dependencies are:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>imap</artifactId>
<version>1.6.0</version>
</dependency>
Neither javax.mail-api nor imap include a com.sun.mail.util package, but it seems to be no longer part (if it ever officially was) of the JRE.
So, I guess this is a bug in the Oracle imap provider that pops up now in the presence of Jigsaw, or am I missing something?
Interestingly, the Eclipse compiler doesn't complain.

Thanks to EJP:
com.sun.mail:imap works with com.sun.mail:javax.mail, but not with javax.mail:javax.mail-api.
The latter does not include the com.sun.mail.util package.
com.sun.mail:imap does not declare any Maven dependency, but de facto it has a compile dependency to com.sun.mail:javax.mail.

Related

Flink-orc: Could not find any format factory for identifier 'orc' in the classpath

I need to save the table result to orc on S3, and this is how I do it:
tEnv.createTemporaryTable("my_output_table", TableDescriptor.forConnector("filesystem")
.schema(outputSchema)
.option("path", s3OutputPath)
.format(FormatDescriptor.forFormat("orc").build())
.build());
finalResultToInsert.executeInsert("my_output_table");
However, during runtime it throws error of
Caused by: org.apache.flink.table.api.ValidationException: Could not find any format factory for identifier 'orc' in the classpath.
at org.apache.flink.table.filesystem.FileSystemTableSink.<init>(FileSystemTableSink.java:128) ~[flink-table_2.12-1.14.2.jar:1.14.2]
at org.apache.flink.table.filesystem.FileSystemTableFactory.createDynamicTableSink(FileSystemTableFactory.java:87) ~[flink-table_2.12-1.14.2.jar:1.14.2]
at org.apache.flink.table.factories.FactoryUtil.createTableSink(FactoryUtil.java:179) ~[flink-table_2.12-1.14.2.jar:1.14.2]
at org.apache.flink.table.planner.delegation.PlannerBase.getTableSink(PlannerBase.scala:394) ~[flink-table_2.12-1.14.2.jar:1.14.2]
......
I have already included the relevant dependency
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-orc_2.11</artifactId>
<version>1.14.2</version>
</dependency>
And in the generated jar file I can see the flink orc classes:
org/apache/flink/orc/
org/apache/flink/orc/AbstractOrcFileInputFormat.class
org/apache/flink/orc/OrcFileFormatFactory$1.class
org/apache/flink/orc/OrcFilters$LessThanEquals.class
org/apache/flink/orc/AbstractOrcFileInputFormat$OrcVectorizedReader.class
org/apache/flink/orc/OrcFilters$Not.class
org/apache/flink/orc/OrcFileFormatFactory.class
org/apache/flink/orc/OrcColumnarRowSplitReader.class
org/apache/flink/orc/OrcColumnarRowSplitReader$ColumnBatchGenerator.class
org/apache/flink/orc/AbstractOrcFileInputFormat$OrcReaderBatch.class
org/apache/flink/orc/OrcFilters$In.class
......
So I really don't understand why it still can not find it in the classpath.
A side note, in the project I also include flink-avro dependency and if I change the output format from orc to avro it just works fine.
Also, I am running the job on AWS EMR. The EMR release is 6.6.0 which has Flink version of 1.14.2. https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-660-release.html
Could anyone help with that? Thanks a lot!
If I'm not mistaken, ORC requires Hadoop. So you should also add org.apache.hadoop:hadoop-common and potentially other Hadoop dependencies too.
Ok, looks like I resolved the problem by placing
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-orc_2.11</artifactId>
<version>1.14.2</version>
</dependency>
To the top of the dependencies section in Maven pom, and it worked.
I think it is just due to the order of class loading, so put it in front might resolve the conflicts during the class loading for flink-orc dependency since it will be loaded first.

How to install Apache Camel?

How do you install Apache-Camel?
I've just started reading 'Camel in Action' 2nd ed.
In section 1.2.1, is suggests downloading the binary distribution.
I found this link to from the releases page:
Release 2.24.1
But I can only see a source-code download.
I've tried to compile from the source, but that always encounters an error.
How do you just install the binary on either Ubuntu/Redhat/Fedora?
Or have I misunderstood Apache-Camel as being a library that you can just install?
Must it always be compiled with maven?
Camel, Java-projects and build-tools
Apache Camel works like any other Java library or framework, meaning that in order to use the framework you'll have to include its java binaries (i.e .jar files) to your project as dependencies. Now to make things simpler most developers use either Maven or Gradle to create, manage and build their java projects.
From these two I would recommend Maven as it seems to be the preferred option for Camel developers with most examples (including ones in official camel site) using it. To install maven follow the official how to install maven guide.
Maven archetypes
To create example camel project you can use maven archetypes which are basically project templates that can be used to create various types of new projects. If you're reading Camel in Action you might be better off using Camel version 2.x.x in your projects with Java Development Kit version 8. Camel 3.x.x is pretty similar so it should be fairly easy to learn that after learning the basics with 2.x.x.
After installing maven you can use your Java IDE (i.e IntelliJ, VSCode, Eclipse or Netbeans) to create project from maven archetype with groupId: org.apache.camel.archetypes artifactId: camel-archetype-java and version: 2.25.4
Or use maven command line command:
# Create new camel java project for Camel version 2.25.4
mvn archetype:generate -DarchetypeGroupId="org.apache.camel.archetypes" -DarchetypeArtifactId=camel-archetype-java -DarchetypeVersion="2.25.4"
Camel project
The new project should contain project file pom.xml where you can specify all the dependencies for your project. The the camel-archetype-java should have the following dependencies listed in the dependencies section of pom.xml.
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>runtime</scope>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
The example route in camel-archetype-java archetypes Myroutebuilder.java is pretty complex for beginners. Hello world on a timer is generally a more simpler test on to see if things work.
package com.example;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
public class MyRouteBuilder extends RouteBuilder {
public void configure() {
// from("file:src/data?noop=true")
// .choice()
// .when(xpath("/person/city = 'London'"))
// .log("UK message")
// .to("file:target/messages/uk")
// .otherwise()
// .log("Other message")
// .to("file:target/messages/others");
from("timer:timerName?period=3000")
.routeId("helloWorldTimer")
.log(LoggingLevel.INFO, "Hello world");
}
}
The project generated from archetype comes with exec-maven-plugin which allows you to run the project with mvn exec:java
Java development kit - JDK
If you're using JDK 11 instead of JDK 8 you'll have to modify maven-compiler-plugin configuration a bit.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<!--
<source>1.8</source>
<target>1.8</target>
-->
<source>11</source>
<target>11</target>
</configuration>
</plugin>
If you've multiple versions of JDK installed you'll have to configure your IDE to use the correct one for the project. With IntelliJ you can configure JDK used by the project from project structure settings.
With VSCode you'll need both JDK 11 and JDK 8 as VSCode Java extensions require JDK 11 to run.
Example settings.json entries for OpenJDK:
"java.configuration.runtimes": [
{
"name": "JavaSE-11",
"path": "C:\\Program Files\\AdoptOpenJDK\\jdk-11.x.x.xxx-hotspot",
"default": true
},
{
"name": "JavaSE-1.8",
"path": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.xxx-x",
}
],
"java.home": "C:\\Program Files\\AdoptOpenJDK\\jdk-11.x.x.xxx-hotspot"
You might also want to setup your path variable so that java -version returns correct version from the command-line.
What you really need is download the binaries for Apache Camel. The best way to get them is make use of maven (https://maven.apache.org/install.html), and existing project from GitHub and get started.
You can go to the following link: https://github.com/dilipsundarraj1/TeachApacheCamel. You can either download the project as zip file or clone the project (you need to have git installed on your machine).
After you downloaded / cloned the project use go to one of the projects: learncamel-simple-file and open the folder in command prompt.
In the command prompt run the command mvn dependency:resolve. (I am assuming you have maven and java installed on your machine). This command will download all the required binaries in the folder: c:\user\<userid>\.m2\repository, where userid is specific to you machine.
Hope it helps.

How to make a JDBC connection to MS SQL Server on Azure via Azure Active Directory User

I have a J2EE web application. Database connection is made via JDBC. Now the web application needs to be deployed on Azure cloud. The JDBC Connection needs to be made to MS SQL Server . Authentication to database is 'ActiveDirectoryPassword'
I found the java libraries. It seems the code is looking for older library: adal4j-1.6.6.jar instead of the newer version: msal4j-1.7.1.jar
With msal4j-1.7.1 loaded I still get the error message: Failed to load ADAL4J Java library.
With the older library I get a different message & log entry :
With the older library I get a different message & log entry:
10-20#16:19:22293041 ERROR [http-nio-8080-exec-9] labware.web.admin.DataSourceBean - Error saving data source in method saveDS.
java.lang.NoClassDefFoundError: com/nimbusds/oauth2/sdk/AuthorizationGrant
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.adalContextExists(SQLServerConnection.java:4546)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.getFedAuthToken(SQLServerConnection.java:4438)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.onFedAuthInfo(SQLServerConnection.java:4415)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.processFedAuthInfo(SQLServerConnection.java:4380)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onFedAuthInfo(tdsparser.java:289)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:125)
I am adding the missing jars. But it seems there should be better way of doing this . Any help in this regard will be highly appreciated.
Was easy problem to fix by using maven. Microsoft Azure jdbc drivers does not come with run time dependency jars it needs. Easy fix is to use maven. The pom.xml should have the following dependencies. As guessed, Maven does all the hard work downloads all the dependency jars.
Following dependency enteries are needed in your pom.xml
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.4.1.jre8</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.6.6</version>
</dependency>
adal4j is needed, the azure gives us the capacity to log into sql server using a federated or active directory user via oauth 2.0.

How do I fix this AbstractMethodError when I try to get Pellet working with OWL API?

I'm getting this error:
Exception in thread "main" java.lang.AbstractMethodError
at org.semanticweb.owlapi.OWLAPIServiceLoaderModule.lambda$loadFactories$1(OWLAPIServiceLoaderModule.java:97)
at java.util.ArrayList.forEach(Unknown Source)
at org.semanticweb.owlapi.OWLAPIServiceLoaderModule.loadFactories(OWLAPIServiceLoaderModule.java:95)
at org.semanticweb.owlapi.OWLAPIServiceLoaderModule.configure(OWLAPIServiceLoaderModule.java:52)
at com.google.inject.AbstractModule.configure(AbstractModule.java:62)
at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
at com.google.inject.spi.Elements.getElements(Elements.java:110)
at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:73)
at com.google.inject.Guice.createInjector(Guice.java:62)
at org.semanticweb.owlapi.apibinding.OWLManager.createInjector(OWLManager.java:104)
at org.semanticweb.owlapi.apibinding.OWLManager.getOWLDataFactory(OWLManager.java:63)
at OntController.<init>(OntController.java:86)
at Driver.main(Driver.java:9)
whenever I try to use OWLManager, i.e. df = OWLManager.getOWLDataFactory(); or manager = OWLManager.createOWLOntologyManager();.
I've noticed that this error started appearing ever since I imported Pellet via maven. This is the dependency tag in my pom.xml:
<dependency>
<groupId>com.github.ansell.pellet</groupId>
<artifactId>pellet-owlapiv3</artifactId>
<version>2.3.3</version>
</dependency>
Is there a way to get Pellet and the latest version of OWL API working? I'm not sure how to resolve this error.
You are running Pellet with OWLAPI 5. Pellet has no releases compatible with owlapi 5, you need to use the latest Openllet release.

Gradle with Integrated SQL Security

I'm currently working on converting one of our Maven projects to use Gradle.
Here is the issue I'm currently facing:
This project is using SQL Integrated security. Here is how Maven handles it (this took us a while to figure it out):
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/sqljdbc4.jar</systemPath>
</dependency>
after run gradle init --type pom
this specific dependency has been converted to something like this:
system group: 'com.microsoft.jdbcdriver', name: 'sqljdbc', version:'4.0.1'
which is not right. Gradle can't build. More specifically, the system scope does not even exist in Gradle's API (neither I found it in any third party Gradle plugin).
Any help from whom had any experience with Gradle SQL integrated security would highly appreciated.
It is very easy to emulate scope system with Gradle by adding a configuration.
Create configuration system and set it as the compile classpath. Any dependencies added to system will now be available during compilation (though I doubt you need a specific JDBC driver for compilation), but the dependencies in system will not be added to the published dependencies of the module:
configurations {
system.extendsFrom compile
}
sourceSets {
main {
compileClasspath = configurations.system
}
}
Now you can easily add the JAR of the JDBC driver to the system configuration. This assumes you still want to refer to a local file just like with Maven:
dependencies {
system files('libs/sqljdbc-4.0.1.jar')
}
But if you have the JAR in a (local) repository, it is better to use the repository:
dependencies {
system 'com.microsoft.jdbcdriver:sqljdbc:4.0.1'
}

Resources