I have a question about how the serviceloader changed in Java 9 based on this scenario
Scenario
Project gert Class Main
package gert;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class Main {
static public void test() throws JAXBException {
InputStream is = new ByteArrayInputStream("<Classes RUNTIME_INCLUDE_JARS=\"\"><Class></Class></Classes>".getBytes(StandardCharsets.UTF_8));
JAXBContext jaxbContext = JAXBContext.newInstance(ClassesDef.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.unmarshal(is);
}
}
Project gert Class ClassesDef
package gert;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Classes")
public class ClassesDef {
@XmlAttribute(name="RUNTIME_INCLUDE_JARS")
public String jars=null;
@XmlElement(name="Class")
public String classes;
}
Project gert pom.xml
<project xmlns="http://ift.tt/IH78KX" xmlns:xsi="http://ift.tt/ra1lAU" xsi:schemaLocation="http://ift.tt/IH78KX http://ift.tt/VE5zRx">
<modelVersion>4.0.0</modelVersion>
<groupId>gert</groupId>
<artifactId>gert</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>gert.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency><!-- org.eclipse.persistence.jaxb.JAXBContextFactory comes with this dependency-->
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.26</version>
</dependency>
</dependencies>
</project>
Project cristina Class Main
package cristina;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
String bWithDep = "C:\\Users\\gert\\eclipse-workspace91java\\gert\\target\\gert-0.0.1-SNAPSHOT-jar-with-dependencies.jar";
List<URL> jars = new java.util.ArrayList<URL>();
File f;
f = new File(bWithDep);
jars.add(f.toURL());
URL[] urls = (URL[])jars.toArray(new URL[jars.size()]);
URLClassLoader urlloader = URLClassLoader.newInstance(urls, ClassLoader.getSystemClassLoader());
System.out.println("Before\tgert.Main.test();.");
Class<?> c= Class.forName("gert.Main", true, urlloader);
Object gert = c.newInstance();
Method m = c.getMethod("test");
m.invoke(gert);
System.out.println("After\tgert.Main.test();.");
}
}
Project cristina pom.xml
<project xmlns="http://ift.tt/IH78KX" xmlns:xsi="http://ift.tt/ra1lAU" xsi:schemaLocation="http://ift.tt/IH78KX http://ift.tt/VE5zRx">
<modelVersion>4.0.0</modelVersion>
<groupId>cristina</groupId>
<artifactId>cristina</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- <dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.26</version>
</dependency> -->
</dependencies>
</project>
So the cristina main loads the gert project and executes a method of gert named test()
Testing
Java 8
When the project is run with java 8 it works
Command
"C:\Program Files\Java\jre1.8.0_151\bin\java.exe" -cp C:\Users\gert\eclipse-workspace91java\cristina\target\cristina-0.0.1-SNAPSHOT.jar cristina.Main
Output
Before gert.Main.test();. After gert.Main.test();.
Java 9
When the same is done with java 9 it doesnt
Command
"C:\Program Files\Java\jre-9.0.1\bin\java.exe" -cp C:\Users\gert\eclipse-workspace91java\cristina\target\cristina-0.0.1-SNAPSHOT.jar cristina.Main
Output
Before gert.Main.test();.
Exception in thread "main" java.lang.reflect.InvocationTargetException
at http://ift.tt/2tn7UHR(Native Method)
at http://ift.tt/2xHLRk5(Unknown Source)
at http://ift.tt/2kgGdjs(Unknown Source)
at http://ift.tt/2wE83Yn(Unknown Source)
at cristina.Main.main(Main.java:23)
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.eclipse.persistence.jaxb.JAXBContextFactory]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:397)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
at gert.Main.test(Main.java:14)
... 5 more
Caused by: java.lang.ClassNotFoundException: org.eclipse.persistence.jaxb.JAXBContextFactory
at http://ift.tt/2itv8uy(Unknown Source)
at http://ift.tt/2z2MOVc(Unknown Source)
at http://ift.tt/2z62oMq(Unknown Source)
at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276)
... 9 more
The 2 above are done directly from the command line.
BUT
When I uncomment the dependencies in the pom.xml of the cristina project and I do a maven install and run the project from eclipse, java 9 works. So it seems that eclipse also takes the maven dependencies into consideration when running a project.
Question
When the dependencies are in the gert project and only used by the gert project why does the cristina project throw an exception when running it with Java 9?
Aucun commentaire:
Enregistrer un commentaire