使用jaxb api的java类在jira中失败:未找到提供程序com.sun.xml.bind.v2.ContextFactory

使用jaxb api的java类在jira中失败:未找到提供程序com.sun.xml.bind.v2.ContextFactory,java,command-line,jaxb,launch,Java,Command Line,Jaxb,Launch,我正在为Jira编写一个插件,它涉及XML文档的解析。我正在使用JAXB(XML到POJO,反之亦然) 因此,我们有一个使用JAXB从POJO生成XML的类。看起来 import javax.xml.bind.*; Class Parser { public void m1() { ... // code which uses classes in javax.xml.bind.* } public static void main(String args[]){

我正在为Jira编写一个插件,它涉及XML文档的解析。我正在使用JAXB(XML到POJO,反之亦然) 因此,我们有一个使用JAXB从POJO生成XML的类。看起来

import javax.xml.bind.*;

Class Parser {
  public void m1() {
    ...
    // code which uses classes in javax.xml.bind.*
  }

  public static void main(String args[]){
   Parser p=new Parser();
   p.m1();

  } 
}
上述包将随JDK发行版(rt.jar)一起提供。因此,我没有传达任何其他信息来管理课程

当我使用“java”从命令行启动它时,它工作正常。但是,当我打包的时候 它作为一个jar,并将其作为插件放在Jira中,它失败了,出现以下错误

javax.xml.bind.JAXBException: Provider com.sun.xml.bind.v2.ContextFactory not found
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:152)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:299)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
这是在同一台机器上。我能看到的唯一不同之处在于,它不同于从命令行启动,当我在Jira中部署它时,它不是通过实例化调用main()而是调用m1()


我想知道发生了什么事!它在同一台机器上。我不知道Jira是如何启动应用程序的(因为我是从命令行启动的)。

com.sun.xml.bind包是JAXB RI()的一部分,所以您可能在类路径的某个地方有它

Java6在
com.sun.xml.internal.bind
包中包含了自己的JAXB版本,因此您通常不需要Java6中的RI


RI可以与Java6配合使用,但这是一场艰苦的战斗,通常会出现这种问题。

最后我找到了原因

在JIRA(Felix)中加载插件时,涉及到许多
类加载器。不会委托给“引导程序”
ClassLoader
。这就是问题所在

要知道哪个
ClassLoader
加载了
JAXBContext
类,请使用
JAXBContext.class.getClassLoader()
,它将打印一些Felix
ClassLoader

它从
jaxbapi.jar
加载类,而不是依赖
rt.jar
,但它们实现的类略有不同
rt.jar
version使用
com.sun.xml.bind.internal.v2.ContextFactory
其中
jaxb api
版本使用
com.sun.xml.bind.v2.ContextFactory

我能够使用JAXB的overloded方法解决这个问题,该方法将采用另一个参数
ClassLoader


花了不少时间。但是,我对其中的细节感到惊讶&我的无知

我知道这是一个比较晚的答案,但是对于在这里登陆的人来说,在为JIRA(和其他Atlassian产品)开发插件时,有一些事情在其他帖子中没有提到

First JIRA,或者说Atlassian,有两种类型的插件,请参见

因为它是一个ClassNotFoundException(和JIRA v4.0.1),所以我假设该插件是一个Plugin2,可以在JIRA v4和更高版本中使用

从JIRAV4开始,JIRA充当OSGi容器,因此Plugin2是一个OSGi包。在OSGi中,每个bundle都有自己的类装入器集。这使得不同的bundle可以拥有相同jar的不同版本,并且可以进行热部署。然而,问题是,并非所有来自JDK的包都默认可用于这些类加载器。这将在上的下进行解释。更详细的描述可以在Springsource的博客中找到。第二段甚至有标题NoClassDefFoundError:com.sun…

理论就这么多

使用Atlassian SDK为JIRA开发插件时,Maven在幕后使用,请参阅。因此,插件项目中将有一个pom.xml。要在插件中包含JDK包,可以向maven jira插件添加
标记(对于其他Atlassian产品,有一个相应的maven插件),并设置bootdelegation属性(您可能希望将maven编译器插件的java设置为1.6):

。。。
com.atlassian.maven.plugins
和

在依赖项下,可以设置所需的jaxb api版本:

...
<dependencies>
    <dependency>
        <groupId>com.atlassian.jira</groupId>
        <artifactId>atlassian-jira</artifactId>
        <version>${jira.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.atlassian.plugins.rest</groupId>
        <artifactId>atlassian-rest-common</artifactId>
        <version>2.5.0</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.4</version>
        <scope>provided</scope>
    </dependency>
    ...
</dependencies>
...
。。。
com.atlassian.jira
(与插件、捆绑包和OSGi的页面相同,但更进一步)


感兴趣的用户可以在和上了解更多信息。

您正在构建哪个JDK版本?JIRA在运行什么JDK?JIRA的哪个版本?JDK的版本是'1.6.0_15',JIRA的版本是'4.0.1',JIRA运行在同一台机器上,所以应该使用相同的JDKhey,我来过这里没问题,但我仍然想知道为什么它无法理解这一点?没有。我已经清除了我的路径。到目前为止,我所了解的情况是,当我使用rt.jar中的“javax.xml.bind.*”时(这些类可能在内部使用com.sun.xml.internal.bind.*)。当我通过CL运行我的程序时,“引导类加载器”正在加载所需的类,以便程序顺利运行。当我在Jira(tomcat)中部署它时,其他一些“类加载器”正在尝试加载这些类,并导致了问题希望我是清楚的。这里是我真的需要一些帮助的链接,我不知道发生了什么。
jaxb-api.jar
是jaxb-RI的一部分,这是我之前建议的,还有实现包名称。ernesto,您是如何/什么重载来指定不同的引导加载程序的。我试着用jython来处理和解包,得到了相反的错误。找到com.sun.xml.bind.v2.ContextFactory,但找不到com.sun.xml.internal.bind.v2.ContextFactory。从jython,JAXBContext.getClassLoader()方法返回org.python.core.SyspathJavaLoader
...
<dependencies>
    <dependency>
        <groupId>com.atlassian.jira</groupId>
        <artifactId>atlassian-jira</artifactId>
        <version>${jira.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.atlassian.plugins.rest</groupId>
        <artifactId>atlassian-rest-common</artifactId>
        <version>2.5.0</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.4</version>
        <scope>provided</scope>
    </dependency>
    ...
</dependencies>
...