2010-06-22 2 views
5

Ich schreibe ein Plugin für Jira, die Parsing von XML-Dokumenten beinhaltet. Ich benutze JAXB, um dies zu tun (XML zu pojos und umgekehrt) So haben Sie eine Klasse, die XML aus Pojos mit JAXB generiert. es sieht aus wie ...Java-Klasse mit Jaxb API fehlgeschlagen in Jira mit: Provider com.sun.xml.bind.v2.ContextFactory nicht gefunden

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(); 

    } 
} 

Die genannten Pakete werden mit JDK-Distribution (rt.jar) kommen. also habe ich nichts weiter über die Klasse verteilt.

Wenn ich es über die Befehlszeile mit 'Java' starte, funktioniert es richtig. aber, wenn ich es als JAR-Paket und setzen es als Plug-in Jira es mit dem folgenden Fehler Fehler

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) 

Dies ist auf der gleichen Maschine. Der einzige Unterschied, den ich sehen konnte, ist anders als das Starten von der Kommandozeile aus, wenn ich es in Jira eingesetzt habe, ruft es nicht main() sondern m1() auf, indem es instanziiert.

Ich frage mich, was passiert! Es ist auf der gleichen Maschine. Ich weiß nicht, wie Jira die Anwendung startet (wie ich von der Kommandozeile aus starte).

+0

Auf welche JDK-Version bauen Sie auf? Auf welchem ​​JDK läuft JIRA? Welche Version von JIRA? – skaffman

+0

JDK-Version ist '1.6.0_15' & Jira-Version ist '4.0.1' Jira läuft auf dem gleichen Rechner, sollte also das gleiche JDK verwenden – ernesto

+0

hey, ich kam acroos diese http://java.sun.com/products/ jdk/faq/faq-sun-packages.html okay, aber ich frage mich immer noch, warum es gescheitert – ernesto

Antwort

0

Das com.sun.xml.bind Paket ist Teil des JAXB RI (http://jaxb.dev.java.net/), Sie haben es wahrscheinlich irgendwo auf Ihrem Klassenpfad.

Java6 hat eine eigene Version von JAXB im Paket com.sun.xml.internal.bind, so dass Sie normalerweise die RI in Java6 nicht benötigen.

Die RI kann gemacht gemacht, um mit Java6 zu arbeiten, aber es ist bergauf Kampf, und endet normalerweise mit dieser Art von Problem.

+0

nein. Ich habe meinen CLASSPATH gelöscht. soweit ich verstehe, was passiert ist, wie ich 'javax.xml.bind. *' in RT verwendet.jar (wahrscheinlich verwenden diese Klassen intern com.sun.xml.internal.bind. *). Wenn ich mein Programm durch CL starte, lädt 'Bootstrap Class Loader' die benötigten Klassen, damit das Programm reibungslos läuft. Wenn ich es in Jira (Tomcat) bereitstellen, versucht ein anderer 'ClassLoader', die Klassen zu laden und das Problem zu verursachen – ernesto

+0

hoffe ich war klar. hier ist der Link http://www.developer.com/java/other/article.php/10936_2248831_2/Java-Class-Loading-The-Basics.htm Ich brauche wirklich etwas Hilfe Ich verstehe nicht, was los ist. – ernesto

5

Endlich konnte ich den Grund herausfinden.

Es gibt viele ClassLoaders beteiligt beim Laden der Plugins in JIRA (Felix). die nicht an 'Bootstrap' delegieren ClassLoader. Und daher das Problem.

Um zu wissen, welche ClassLoader die JAXBContext Klasse geladen, verwenden JAXBContext.class.getClassLoader() die einige Felix ClassLoader gedruckt wird.

Es lud die Klasse von jaxb-api.jar statt auf rt.jar angewiesen, aber sie implementiert die Klassen etwas anders. rt.jar Version verwendet com.sun.xml.bind.internal.v2.ContextFactory wo jaxb-api Version verwendet com.sun.xml.bind.v2.ContextFactory.

Ich bin in der Lage, das Problem mit der überladenen Methode von JAXB zu lösen, die einen anderen Parameter als ClassLoader nehmen wird.

Es hat ziemlich lange gedauert. Aber ich bin überrascht von den inneren Details & meine Ignoranz

+2

kann ich für mich selbst wählen ? – ernesto

+0

umm .. 2 Stunden! Ich liebe SOF – ernesto

+0

'jaxb-api.jar' ist Teil des JAXB RI, was ich bereits vorgeschlagen habe, ebenso wie die Namen der Implementierungspakete. – skaffman

6

Ich weiß, dass dies eine Art späte Antwort ist, aber für Leute, die hier landen, gibt es ein paar Dinge, die nicht in den anderen Posts erwähnt werden, die wichtig sind, wenn Plug- Ins für JIRA (und andere Atlassian-Produkte).

Erster JIRA oder vielmehr Atlassian, hat zwei Arten von Plug-In finden Sie Differences between Plugins1 and Plugins2

Da es ein ClassNotFoundException (und JIRA v4.0.1) war, nehme ich die Plug-in einer plugin2 ist, der in JIRA v4 und höher verwendet werden.

Ab JIRA v4 fungiert JIRA als OSGi-Container und daher ist Plugin2 ein OSGi-Bundle. In OSGi hat jedes Bundle eigene Klassenladeprogramme. Auf diese Weise können verschiedene Bundles unterschiedliche Versionen derselben JAR-Dateien enthalten und unter anderem auch hot bereitgestellt werden. Der Catch ist jedoch, dass nicht alle Pakete aus dem JDK standardmäßig für diese Klassenlader verfügbar sind. Dies wird unter Plugins, bundles and OSGi über die Atlassian Developers web page erläutert. Eine genauere Beschreibung finden Sie im Blog Exposing the boot classpath in OSGi bei Springsource. Der zweite Absatz dort hat sogar den Titel NoClassDefFoundError: com.sun ...

So viel für die Theorie. Bei der Entwicklung eines Plug-ins für JIRA mit dem Atlassian SDK wird Maven im Hintergrund verwendet, siehe Atlassian Plugin SDK Documentation. Es wird also eine pom.xml im Plug-in-Projekt geben. Um JDK-Pakete im Plugin zu enthalten, kann man einen <SystemProperties> Tag der Maven-jira-Plugin hinzufügen (für andere Atlassian Produkte, gibt es eine entsprechende Maven Plugin), und stellen Sie die bootdelegation Eigenschaft (und Sie vielleicht möchten Java 1.6 für die maven-Compiler-Plugin) setzen:

... 
<build> 
    <plugins> 
     <plugin> 
      <groupId>com.atlassian.maven.plugins</groupId> 
      <artifactId>maven-jira-plugin</artifactId> 
      <version>3.7.3</version> 
      <extensions>true</extensions> 
      <configuration> 
       <productVersion>${jira.version}</productVersion> 
       <productDataVersion>${jira.data.version}</productDataVersion> 
       <systemProperties> 
        <property> 
         <name>atlassian.org.osgi.framework.bootdelegation</name> 
         <value>sun.*,com.sun.*</value> 
        </property> 
       </systemProperties> 
      </configuration> 
     </plugin> 
     <plugin> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <configuration> 
       <source>1.6</source> 
       <target>1.6</target> 
      </configuration> 
     </plugin> 
     ... 
    </plugins> 
</build> 
... 

die aufgeführten Pakete werden dann auf das Bündel zur Verfügung stehen. Beachten Sie jedoch, dass die Boot-Delegierung keine Lösung für alle Probleme ist und nur mit Einschränkungen verwendet werden sollte. Lesen Sie mehr unter Boot Delegation und Avoid Classloader Hacks.

Unter den Abhängigkeiten kann man setzt die jaxb-api Version benötigt:

... 
<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> 
... 

Es ist nicht immer nötig, explizit eine Abhängigkeit von jaxb-api zu haben. Zum Beispiel hat das atlassian-rest-common Plug-in oben eine transitive Abhängigkeit von jaxb-api. Wichtig ist, die Einstellung scope zu verstehen. Schauen Sie sich Setting OSGi Manifest Instructions in your Plugin (gleiche Seite wie Plugins, Bundles und OSGi aber weiter unten).

Die fasziniert kann mehr bei OSGi Alliance Specifications und OSGi Community Wiki lernen.

Verwandte Themen