JPA findet keinen PersistenceProvider (maven, eclipselink)

derFabi95

Mitglied
Hallo zusammen,

aktuell bin ich für ein 3rd-party-Programm am Entwickeln eines Addons.
Hierbei wird von der eigentlichen Jar nur meine selbstgeschriebene Jar geladen.
Kurz zur Info: Es ist hier eigentlich ein "Crosspost", aber ich habe im entsprechenden Fachforum keinerlei Antwort bekommen... schade!
Hier der Link zum Originalbeitrag: https://www.spigotmc.org/threads/jpa-maven-shade-no-persistence-provider-for-entitymanager.480199/


Ich erhalte hier jedoch immer den folgenden Fehler:
Java:
[javax.persistence.spi] javax.persistence.spi::No valid providers found.
javax.persistence.PersistenceException: No Persistence provider for EntityManager named project_phoenix

Ich nutze bereits das maven-shade-plugin, wodurch die .jar zwar ziemlich groß wird, jedoch die entsprechenden Pfade korrekt eingebunden werden.

Ich kann verifizieren dass alle benötigten Abhängigkeiten (org.eclipse.persistence.jpa, mysql-connector-java und javax.persistence-api) auch korrekt über das Shade eingebunden und verfügbar sind.

Natürlich ist in der persistence.xml (unter resources/META-INF) auch der PersistenceProvider angegeben:
Java:
<persistence-unit name="project_phoenix" transaction-type="RESOURCE_LOCAL">

Ich vermute also einen Fehler im Classpath. Wobei ich zugeben muss, ich verstehe noch nicht so ganz wie der ClassPath funktioniert.
Gibt es denn, um den Fehler einzugrenzen, eine Möglichkeit den "Suchpfad" für die persistence.xml zu printen?

Achja: Frohes neues Jahr 2021 allen :)
 
Zuletzt bearbeitet:

derFabi95

Mitglied
Erstmal danke für deine Antwort!
Ich seh nix, außer ein persistence-unit-Tag.
Ups, da bin ich in der Zeile beim Kopieren verrutscht. Na, dann häng ich doch mal die ganze persistence.xml an:
Java:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="project_phoenix" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
            <property name="javax.persistence.schema-generation.scripts.action" value="create"/>
            <property name="eclipselink.ddl-generation" value="create-tables"/>
        </properties>
    </persistence-unit>
</persistence>
 
Zuletzt bearbeitet:

derFabi95

Mitglied
Ich würde mal die Klassen aufführen bzw. exclude-unlisted-classes auf false setzen und die Verbindungsparameter angeben (s. https://www.eclipse.org/eclipselink/documentation/2.5/solutions/testingjpa002.htm)
Die Verbindungsparameter habe ich mittels Properties in meiner Hauptklasse eingebunden, da diese aus einer Datei geladen werden sollen.
Ich habe nun auch einmal eine Entity-Klasse angegeben, das hat jedoch nichts geändert, die Fehlermeldung bleibt wie gehabt bestehen.
Hätte mich auch gewundert, meines Wissens nach muss ja der PersistenceProvider ohne Entity-Klassen auch funktionieren, oder?
 

derFabi95

Mitglied
Theoretisch schon. Es ging nur darum, mögliche Fehlerquellen auszuschließen.

Hab das mal eben getestet: der Spaß funktioniert einwandfrei.
Hm.
Das wiederum würde ja meine Vermutung bestätigen, dass es etwas mit dem ClassPath zu tun hat.
Wie im Hauptthread geschrieben handelt es sich um ein "Addon", das durch eine andere Jar geladen wird...
Demnach wäre ja vermutlich der ClassPath auf der "Haupt"-jar, oder nicht? Das ist jetzt nur eine reine Mutmaßung, ehrlich gesagt versteh ich die ganzen Zusammenhänge und Auswirkungen des ClassPaths nicht wirklich.
 

mihe7

Top Contributor
Der Class-Path als solches ist hier nicht das Problem. Viel interessanter sind hier ClassLoader. Da Du aber mit dem shade-Plugin arbeitest, werden Klassen mit dem gleichen ClassLoader geladen und somit auch gefunden. Die Fehlermeldung kommt ja von einer Eclipselink-Klasse. Es sieht eher so aus, als ob die persistence.xml nicht geladen wird.
 

mihe7

Top Contributor
Dazu habe ich echt keine Idee, denn normalerweise sollte das funktionieren. Außerdem müsste die Fehlermeldung eine andere sein, wenn die persistence.xml nicht geladen bzw. gefunden wird (persistence unit <name> not found oder ähnliches). Irgendwas scheint hier durcheinander zu kommen.

Ah, ich habe gerade die pom.xml (Crosspost) gesehen: probier mal Eclipselink 2.7.8, MySQL-Connector 5.1..49 und vor allem: schmeiß die Abhängigkeit zu javax.persistence-api raus.
 

mrBrown

Super-Moderator
Mitarbeiter
sind dann da die Versionen inkompatibel oder wie erklärst du dir das?
So in etwa, Eclipselink 3.0 läuft mit JakartaEE, Eclipselink 2 mit JavaEE. Genutzt hast du in deinem Code vemutlich die JavaEE-APIs, dann wird Eclipselink nicht gefunden.

Du müsstest auch Eclipselink 3 nutzen können, darfst dann nur nicht explizit JPA einbinden, und musst die JPA-imports aus dem jakarta-Package nutzen.
 

fsicher2016

Mitglied
I changed all imports (javax --> jakarta), but now I've an other problem. Here my example (in a short version):

[CODE lang="java" title="The class Person"]
package xxx;

import java.io.Serializable;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.OneToOne;

@Entity
public class Person implements Serializable {

private static final long serialVersionUID = -2854035784525333365L;

@Id
@GeneratedValue
private int id;

private String name;
private String vorname;

public Person() {

}

// etc.

}
[/CODE]

In the persistence.xml I've the following:

[CODE lang="java" title="persistence.xml"]<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

<class>xxx.Person</class>
// etc.[/CODE]

Now, I've the following error message:

Class "xxx.Person" is listed in the persistence.xml file, but is not annotated

I don't understand this messge, because the class is annotated: The annotation @Entity is given in the front of the class.

In the pom.xml I've these dependencies:

[CODE lang="xml" title="pom.xml dependencies"]<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/org.eclipse.persistence.jpa -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>3.0.0</version>
</dependency>[/CODE]

Are my dependencies wrong? If not, what is wrong in my code?

With 'eclipselink 2.8.0' it works fine, but I want to move forward and use eclipselink 3.0 in the future.
 
Zuletzt bearbeitet:

fsicher2016

Mitglied
Vielen Dank, das hat wirklich einen Schritt weiter geholfen.

Wenn ich es mache, werden alle in der persistence.xml aufgelisteten Entity-Klassen aus der persistence.xml entfernt, die Fehlermeldung ist weg. Aber, wenn ich Tests durchführe (egal ob direkt in Eclipse mit Run As --> JUnit Test oder mit Maven bzw. mvn clean verify), bekomme ich jetzt Probleme mit der Verbindung zur DB:

[CODE lang="java" title="Fehlermeldung:"]
[ERROR] jpa.demos.PersonIT.testUpdate() Time elapsed: 0.034 s <<< FAILURE!
jakarta.persistence.PersistenceException:
Exception [EclipseLink-4021] (Eclipse Persistence Services - 3.0.0.v202012081010): org.eclipse.persistence.exceptions.DatabaseException
Exception Description: Unable to acquire a connection from driver [null], user [null] and URL [null]. Verify that you have set the expected
driver class and URL. Check your login, persistence.xml or sessions.xml resource. The jdbc.driver property should be set to a class that is
compatible with your database platform
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:853)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:222)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:330)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:350)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
at jpa.demos.util.JpaUtil.createEntityManager(JpaUtil.java:28)
at jpa.demos.PersonIT.testUpdate(PersonIT.java:85)
Caused by: Exception [EclipseLink-4021] (Eclipse Persistence Services - 3.0.0.v202012081010): org.eclipse.persistence.exceptions.DatabaseExce
ption
Exception Description: Unable to acquire a connection from driver [null], user [null] and URL [null]. Verify that you have set the expected
driver class and URL. Check your login, persistence.xml or sessions.xml resource. The jdbc.driver property should be set to a class that is
compatible with your database platform
at org.eclipse.persistence.exceptions.DatabaseException.unableToAcquireConnectionFromDriverException(DatabaseException.java:387)
at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:95)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:172)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:225)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:807)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:256)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:766)
... 19 more[/CODE]

Die Treiber-Jar ist aber in "Maven Dependencies" zu sehen: postgresql-42.2.5.jar. Habe noch mit Derby getestet (derby.jar, Version 10.14.2.0 mit EmbeddedDriver), das Problem bleibt aber.

Ich verzichte hier auf die Angabe der persistence.xml, weil die beiden Varianten mit org.eclipse.persistence.jp 2.7.8 einwandfrei funktionieren.

Obwohl ich der Meinung bin, dass ich es mit Maven (heisst: unabhängig von einer konkreten IDE) immer und problemlos starten und ausführen können sollte ...

Ich arbeite mit Eclipse IDE (Version: 2020-12 (4.18.0)). Wenn ich auf Projekt gehe (Kontext-Menü) --> Properties --> JPA, sehe ich, dass ich unter "Platform" die EclipseLink 3.0 gar nicht auswählen kann. Wenn ich auf "Change JPA Version", finde ich unter JPA die Version 3.0 nicht. Fehlt da in Eclipse evtl. ein Plugin?
 
K

kneitzel

Gast
Da würde ich eher davon ausgehen, dass die Daten zur Verbindung nicht richtig hinterlegt sind und daher nicht gefunden werden.

Und der Test mit Maven ist für mich immer wichtig: Dann kann es nicht an der IDE (und dort fehlenden Plugins) liegen (meine ich). (IDEs sind generell kleine Divas, die gerne rumzicken. Da ist mein Umgang dann immer die "Hammer-Methode" -> Projekt schließen, die IDE Dateien wegschmeißen und neu öffnen, so dass die IDE noch einmal alles richtig lädt und aufbaut ...)

Da ich nicht den ganzen Thread durchgelesen habe, weiss ich jetzt nicht, ob ich da nicht vielleicht wichtige Dinge übersehen habe und meine Hilfestellung in die falsche Richtung geht. Aber wenn Du Dir z.B.
einmal ansiehst. Da findest Du ein Beispiel, wie dann auch z.B. in der persistence.xml die notwendigen Daten für driver, user und url übergeben werden.
(Sorry, falls es nicht wirklich hilfreich gewesen sein sollte - ist halt ein Versuch auf die Schnelle eine kleine Hilfestellung anzubieten ohne viel Zeit in das Lesen des ganzen Threads zu investieren.)
 

fsicher2016

Mitglied
Vielen Dank für Deine Hilfe.

Ich bin dem Link gefolgt und gesehen, dass die Struktur der Datei persistence.xml an sich korrekt ist. Da sich das Beispiel aber nicht direkt auf EclipseLink 3.0 bezieht, hat mich das auf die Idee gebracht, dass die Namen von Properties evtl. auch angepasst werden müssen, wobei javax durch jakarta ersetzt wird. So wird z.B. javax.persistence.jdbc.driver zu jakarta.persistence.jdbc.driver usw.

Und, das war es! Danach konnte ich problemlos alle Tests durchführen.

Anschliessend habe ich noch eine Seite mit dem Beispiel gefunden, aus dem ersichtlich wird, dass die Namen von Properties in persistence.xml angepasst werden müssen:

https://blog.jetbrains.com/idea/2021/02/creating-a-simple-jakarta-persistence-application/

Kurze gesagt:

Ich habe es verpasst, den Namespace "javax" in der persistence.xml durch "jakarta" auch zu ersetzten.

Vielen Dank.
 

Ähnliche Java Themen

Neue Themen


Oben