有关serviceloader的Java 9依赖性问题 [英] Java 9 dependency issues regarding serviceloader

查看:351
本文介绍了有关serviceloader的Java 9依赖性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,关于如何根据这种情况在Java 9中更改serviceloader

I have a question about how the serviceloader changed in Java 9 based on this scenario

项目 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);
    }
}

项目 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;
}

项目 gert pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <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>

项目 cristina Class 主要

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();.");
    }
}

项目 cristina pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <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>

所以cristina main 加载gert项目并执行gert方法名为 test()

So the cristina main loads the gert project and executes a method of gert named test()

Java 8

当项目使用java 8运行时,它可以工作

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

输出

在gert.Main.test();之前。
gert.Main.test();.



Java 9

完成同样的操作后java 9它没有

Before gert.Main.test();. After gert.Main.test();.
Java 9
When the same is done with java 9 it doesnt

命令

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

输出

Before  gert.Main.test();.
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(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 java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.ClassLoader.loadClass(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

以上2是直接从命令行完成的。

但是

当我取消注释 cristina 项目的 pom.xml 中的依赖项时,我会进行maven安装和从eclipse运行项目,java 9可以正常工作。因此,在运行项目时,eclipse似乎也会考虑maven依赖关系。

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.

当依赖项在 gert 项目中,仅由 gert 项目使用,为什么 cristina 项目在使用Java 9运行时抛出异常?

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?

推荐答案

异常的原因可能是 java.xml .bind 是一个可升级的模块。

The reason for the exception could probably be that java.xml.bind is an upgradeable module.

作为 JEP 261:模块系统在模块的风险和假设中说明:

As the JEP 261: Module System states in the Risks and assumptions for modules :


如果在命名模块和类路径
中定义了包,则将忽略类路径上的包。因此,类路径
不再用于将
构建的包扩充到环境中。

If a package is defined in both a named module and on the class path then the package on the class path will be ignored. The class path can, therefore, no longer be used to augment packages that are built into the environment.



<因此,似乎忽略了包 org.eclipse.persistence.jaxb 。最后,代码行 ContextFinder.newInstance 调用 JAXBContextFactory.createContext ,提供绑定的类( ClassDef )。文档进一步指出

Hence seems like the package org.eclipse.persistence.jaxb is ignored. Eventually, the line of code ContextFinder.newInstance invokes the JAXBContextFactory.createContext with the classes provided to be bound(ClassDef). The documentation further states that


throws JAXBException - 如果在创建时遇到错误 JAXBContext ,例如(但不限于):...

throws JAXBException - if an error was encountered while creating the JAXBContext, such as (but not limited to) : ...


  • classesToBeBound 未对 java.xml.bind 模块开放

  • classesToBeBound are not open to java.xml.bind module

您可以尝试做的是在运行应用程序时使用


What you can try to do is while running the application make use of the

--upgrade-module-path /path/to/jaxb-api/dependency...




A:分隔的目录列表,
每个目录是模块的目录,
替换运行时映像中的可升级模块

A : separated list of directories, each directory is a directory of modules that replace upgradeable modules in the runtime image

这篇关于有关serviceloader的Java 9依赖性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆