hbci4java icon indicating copy to clipboard operation
hbci4java copied to clipboard

ClassNotFoundException with newer jaxb-versions and java 17

Open HoffmannTom opened this issue 3 years ago • 2 comments

Hello, we upgraded to Java 17 and new jaxb libraries. We now get the following exception:

2022-08-11T09:31:52.119+02:00 ERROR InvoiceDownloadServlet: Implementation of JAXB-API has not been found on module path or classpath. javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath. at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.1.jar:2.3.0] at org.kapott.hbci.GV.generators.AbstractSEPAGenerator.marshal(AbstractSEPAGenerator.java:43) ~[hbci4j-core-3.1.37.jar:3.1.37] at org.kapott.hbci.GV.generators.GenLastSEPA00800302.generate(GenLastSEPA00800302.java:161) ~[hbci4j-core-3.1.37.jar:3.1.37] at org.kapott.hbci.GV.generators.GenLastSEPA00800302.generate(GenLastSEPA00800302.java:56) ~[hbci4j-core-3.1.37.jar:3.1.37] at com.xxxxx.downloadSepaXml(InvoiceDownloadServlet.java:200) [classes/:?] .... Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1444) ~[catalina.jar:10.0.18] at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1252) ~[catalina.jar:10.0.18] at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276) ~[jaxb-api-2.3.1.jar:2.3.0]

The jar file jaxb-impl-2.3.6.jar does contain the package com.sun.xml but the newer versions like 3.x or 4.x doesn't. It seems the old sun implementation is somewhere references and not the new glassfish impl. Any help would be appreciated how to fix this reference.

Thanks a lot!

HoffmannTom avatar Aug 11 '22 09:08 HoffmannTom

Die JAXB-Implementierung wurde - wenn ich mich recht erinnere - in Java 17 entfernt. In pom.xml ist ja JAXB referenziert:

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.1</version>
</dependency>

Allerdings nur die API. Dort muss jetzt wohl auch die Implementierung explizit hinzugefügt werden.

willuhn avatar Aug 11 '22 09:08 willuhn

Genau, ab Java 11 wurde JAXB entfernt. Jedoch ist man bei der jaxb-impl auf die 2.3.6 beschränkt. Höhere Versionen besitzen eine glassfish Implementierung und nicht mehr die sun-Implementierung. D.h. mit höheren Versionen erhalte ich die genannte ClassNotFoundException.

HoffmannTom avatar Aug 11 '22 11:08 HoffmannTom

Der Grund ist ein etwas anderer. GlassFish war bereits ein Projekt von SUN, als sie noch eigenständig waren, lange bevor sie von Oracle übernommen wurden. Oracle hat dann 2018 die Entwicklung von Java EE und GlassFish eingestellt und den kompletten Code der Eclipse Foundation übereignet (u.a. ist Java EE deswegen auch nicht mehr im JDK). Da die Java-Namensrechte aber weiterhin bei Oracle liegen, wurde aus Java EE bei Eclipse dann Jakarta EE. Um eine Weiterentwicklung zu gewährleisten, wurde bei der Umstellung von Jakarta EE 8 auf Jakarta EE 9 entschieden, die Namensräume von javax.* u.a. in jakarta.* umzubenennen. Darum sind die höheren Versionen (>= 3.0.0) von JAXB-API und JAXB-RI nicht mehr kompatibel und eine 2er-Version muß weiterhin verwendet werden, solange HBCI4J und Jameica nicht auf Jakarta EE 9 oder 10 umgestellt sind. Zum gegenwärtigen Zeitpunkt wäre das maximal die Version 2.3.3 bei JAXB-API und die Version 2.3.7 bei JAXB-RI.

uhle avatar Feb 06 '23 19:02 uhle

Hallo Uhle, ich denke Du hast das Problem gut beschrieben. Das mit den Namensräumen macht einige Probleme mit den Abhängigkeiten. Die prinzipielle Frage ist, wird es eine hbci4java Version geben, die Jakarta EE kompatibel ist? Andernfalls ist man auf die alten Packages angewiesen und bekommt keine Updates mehr. Eine Umstellung auf Jakarta EE wäre notwendig, um auch mit aktuellen Bibliotheken zusammenzuarbeiten.

thomass4t avatar Feb 06 '23 22:02 thomass4t

Vermutlich wird mehr als nur die Ersetzung der Namensräume notwendig sein, auch wenn es wohl Tools gibt, die einen zumindest bei der Umstellung auf Jakarta EE 9 unterstützen. Aber gerade nach einer so umfassenden Änderung muß ja alles ausgiebig getestet werden.

Was die Updates bzgl. Jakarta EE 8 betrifft, so ist die angesprochene Version 2.3.7 von JAXB-RI erst im letzten Oktober erschienen. Aber ja, wer kann schon in die Zukunft sehen und vorhersagen, wie lange es solche Updates noch geben wird.

uhle avatar Feb 06 '23 22:02 uhle

Die Umstellung auf Jakarta EE geht auch deshalb nicht "mal eben so", weil HBCI4Java nicht nur von Hibiscus verwendet wird sondern auch von einer unüberschaubaren Anzahl von Programmen - oft solche, die gar nicht öffentlich bekannt sind sondern irgendwo in den Integrationen von Zahlungsanbindungen bei Firmen stecken. Mit einer unkoordinierten Umstellung würde man eine Menge Integrationen kaputt machen.

willuhn avatar Feb 07 '23 06:02 willuhn

Man sollte das in einer neuen Major Version starten, denn mehr und mehr wird das gebraucht.

Bei 3.x dann irgendwann nur noch bugs beheben. 4.x als neue major version mit Jakarta EE weiter entwickeln.

Das fände ich gut.

Gruß Janning

Am 7. Februar 2023 07:47:09 schrieb Olaf Willuhn @.***>:

Die Umstellung auf Jakarta EE geht auch deshalb nicht "mal eben so", weil HBCI4Java nicht nur von Hibiscus verwendet wird sondern auch von einer unüberschaubaren Anzahl von Programmen - oft solche, die gar nicht öffentlich bekannt sind sondern irgendwo in den Integrationen von Zahlungsanbindungen bei Firmen stecken. Mit einer unkoordinierten Umstellung würde man eine Menge Integrationen kaputt machen.

-- Reply to this email directly or view it on GitHub: https://github.com/hbci4j/hbci4java/issues/73#issuecomment-1420277332 You are receiving this because you are subscribed to this thread.

Message ID: @.***>

kicktipp avatar Feb 07 '23 07:02 kicktipp

Gute Idee. Die Entwicklung für 4.x sollte dann aber erstmal in einem neuen Branch "4.0" neben "master" geschehen. Ich nehme pern PRs entgegen.

willuhn avatar Feb 07 '23 07:02 willuhn

Das Vorgehen finde ich gut. Bisher habe ich von anderen Bibliotheken zwei Vorgehensweisen gesehen.

  1. Neue Version mit Jakarta EE Kompatibilität erstellen und die alte Version nur noch mit Bugfixes versehen.
  2. Zwei Branches parallel pflegen, eine mit jakarta im Namen , der alte Branch wie bisher

thomass4t avatar Feb 07 '23 08:02 thomass4t

Die beiden Vorgehensweisen schließen sich nicht wirklich aus. In beiden Fällen gibt es zwei separate Entwicklungszweige. Ob auf dem neuen dann "jakarta", "4.0", "next" o.ä. steht (ich hab schon so viele Varianten gesehen), ist nun wirklich nicht so wichtig. Es ist nur ein Name. Und ob auf master (Version 3.1.x) nur noch Bugfixes oder auch mal eine andere Änderung eingepflegt wird, kann vermutlich auch dann entschieden werden, wenn es dazu kommen sollte.

uhle avatar Feb 07 '23 14:02 uhle

Oben ein Pull-Request, der auf die Version jaxb 4.0 aufsetzt und mit jakarta packages arbeitet. Der Pull Request kann für einen neuen jakarta-Branch als Basis verwendet werden. Die Artefakt-ID sollte hierbei angepasst werden, um ein separates Package zu erhalten (z.B. hbci4j-jakarta-core) Falls JDK8 Kompatibilität nicht mehr erforderlich ist, kann ich noch ein paar Warnings per Pull-Request entfernen. Falls beide Branches so ähnlich wie möglich sein sollen, macht es weniger Sinn.

thomass4t avatar Feb 11 '23 18:02 thomass4t

Hab den PR #75 in einen neuen Branch "4.0" gemerged.

willuhn avatar Feb 22 '23 10:02 willuhn

Super, vielen Dank :)

thomass4t avatar Feb 22 '23 12:02 thomass4t

@willuhn Ist es möglich für den Branch 4.0 einen Build zu machen und ins Maven-Repo zu pushen?

HoffmannTom avatar Mar 09 '23 12:03 HoffmannTom

Ich habe ehrlich gesagt keine Ahnung, wie ich es hinkriege, einen abweichenden Branch unter einer anderen artifactId zu publishen. Hat das jemand schonmal gemacht?

willuhn avatar Mar 09 '23 13:03 willuhn

Bleibt die Frage, ob die artifactId auch wirklich unbedingt geändert werden muß. Einige Bibliotheken wie z.B. JAXB API und JAXB Runtime haben nach der Namensraumumbenennung ihre bisherige artifactId auch beibehalten (jaxb-api bzw. jaxb-runtime) und nur einen Versionssprung auf die nächste Major-Revision durchgeführt (in diesem Fall 3.0.0), zumal auch hier hauptsächlich "nur" die Namensräume von javax.* in jakarta.* geändert wurden.

uhle avatar Mar 09 '23 16:03 uhle

Die artifact-id müsste in der pom.xml der Eintrag hier sein: <artifactId>hbci4j-core</artifactId> Der Eintrag kann in Branch 4 angepasst werden.

In der Wildnis habe ich beide Varianten gefunden. Einige fügen -jakarta- im Namen ein, die anderen machen bei Version x einen harten Schnitt hin zu jakarta.

HoffmannTom avatar Mar 10 '23 07:03 HoffmannTom

Die artifact-id müsste in der pom.xml der Eintrag hier sein: hbci4j-core Der Eintrag kann in Branch 4 angepasst werden.

Das weiss ich. Die Frage ist: Reicht die Änderung dort und wird das vom Repo so direkt akzeptiert oder muss das noch irgendwo registriert werden? Und kann ich ein "man release:prepare && mvn release:perform" direkt auf dem Branch machen oder muss der Branch in der pom.xml nochmal explizit angegeben werden?

In der Wildnis habe ich beide Varianten gefunden. Einige fügen -jakarta- im Namen ein, die anderen machen bei Version x einen harten Schnitt hin zu jakarta.

Einfach mit der nächsten Major-Version auf jakarte zu wechseln, brigt das Risiko, unnötig Integrationen zu brechen, da bei den Usern mit Java < 17 plötzlich zusätzliche Abhängigkeiten nötig sind, die vorher nicht erforderlich waren.

willuhn avatar Mar 10 '23 07:03 willuhn

Ich fände es wie folgt am besten:

  • Neue Version 4.x
  • Keine Änderung der artifactId
  • Umstellung auf jakarta und JDK17

So macht das im Moment zb auch Spring Boot und andere. Die Zeit ist jetzt richtig.

Wenn Du jakarta im Namen hast, wirst Du das nie wieder los.

Gruß Janning

Am 10.03.23 um 08:52 schrieb Olaf Willuhn:

Die artifact-id müsste in der pom.xml der Eintrag hier sein:
hbci4j-core Der Eintrag kann in Branch 4 angepasst werden.

Das weiss ich. Die Frage ist: Reicht die Änderung dort und wird das vom Repo so direkt akzeptiert oder muss das noch irgendwo registriert werden? Und kann ich ein "man release:prepare && mvn release:perform" direkt auf dem Branch machen oder muss der Branch in der pom.xml nochmal explizit angegeben werden?

In der Wildnis habe ich beide Varianten gefunden. Einige fügen
-jakarta- im Namen ein, die anderen machen bei Version x einen
harten Schnitt hin zu jakarta.

Einfach mit der nächsten Major-Version auf jakarte zu wechseln, brigt das Risiko, unnötig Integrationen zu brechen, da bei den Usern mit Java < 17 plötzlich zusätzliche Abhängigkeiten nötig sind, die vorher nicht erforderlich waren.

— Reply to this email directly, view it on GitHub https://github.com/hbci4j/hbci4java/issues/73#issuecomment-1463407657, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARJBJMIOXHMU33RGLHQIXTW3LMUNANCNFSM56HOMB7Q. You are receiving this because you commented.Message ID: @.***>

kicktipp avatar Mar 10 '23 08:03 kicktipp

Ich fände es wie folgt am besten:

  • Neue Version 4.x
  • Keine Änderung der artifactId
  • Umstellung auf jakarta und JDK17

Ich halte das auch für die bessere Lösung.

So macht das im Moment zb auch Spring Boot und andere. Die Zeit ist jetzt richtig.

Wenn Du jakarta im Namen hast, wirst Du das nie wieder los.

Das sehe ich persönlich genauso.

Einfach mit der nächsten Major-Version auf jakarte zu wechseln, birgt das Risiko, unnötig Integrationen zu brechen, da bei den Usern mit Java < 17 plötzlich zusätzliche Abhängigkeiten nötig sind, die vorher nicht erforderlich waren.

Das wird sich ohnehin nicht komplett vermeiden lassen, wie der ursprüngliche Problembericht hier (#73) zeigt, zumal Java EE (und damit auch JAXB) bereits seit Java 11 nicht mehr im JDK integriert ist. Ich glaube, es gibt keinen idealen Weg, um Nutzer vor eventuellen Problemen bei unbedarften Updates zu bewahren, da die Situation mit der unterschiedlichen Handhabung bei der Umstellung der einzelnen Bibliotheken auf Jakarta EE nun einmal so ist, wie sie's ist. Entweder ist es die eine oder andere Bibliotheksversion, die ggf. zu neu und damit unpassend zu den anderen ist.

Vielleicht ist es sinnvoll, auf die Umstellung von Java EE auf Jakarta EE bei der Verwendung der Bibliotheken JAXB API und JAXB Runtime in Version 4.0 von HBCI4Java zusätzlich auch in readme.md hinzuweisen.

uhle avatar Mar 10 '23 17:03 uhle

Version 4.0.0 (jakarta.* und 3.1.67 (javax.*) sind online: https://oss.sonatype.org/#nexus-search;gav~com.github.hbci4j~hbci4j-core~~~~kw,versionexpand

willuhn avatar Mar 13 '23 16:03 willuhn

Super, vielen Dank! :)

HoffmannTom avatar Mar 13 '23 16:03 HoffmannTom

Wow! Ich hatte gerade alles andere bei uns auf jakarta umgestellt und wollte mich jetzt hier nützlich machen. Danke, Olaf!

kicktipp avatar Mar 13 '23 17:03 kicktipp