# JPA findet keinen PersistenceProvider (maven, eclipselink)



## derFabi95 (1. Jan 2021)

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:

```
[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: 
	
	
	
	





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


----------



## mihe7 (2. Jan 2021)

derFabi95 hat gesagt.:


> Natürlich ist in der persistence.xml (unter resources/META-INF) auch der PersistenceProvider angegeben:


Ich seh nix, außer ein persistence-unit-Tag.



derFabi95 hat gesagt.:


> Achja: Frohes neues Jahr 2021 allen


Gleichfalls.


----------



## derFabi95 (2. Jan 2021)

Erstmal danke für deine Antwort!


mihe7 hat gesagt.:


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

```
<?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>
```


----------



## mihe7 (2. Jan 2021)

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)


----------



## derFabi95 (2. Jan 2021)

mihe7 hat gesagt.:


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


----------



## mihe7 (2. Jan 2021)

derFabi95 hat gesagt.:


> Hätte mich auch gewundert, meines Wissens nach muss ja der PersistenceProvider ohne Entity-Klassen auch funktionieren, oder?


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

Hab das mal eben getestet: der Spaß funktioniert einwandfrei.


----------



## derFabi95 (2. Jan 2021)

mihe7 hat gesagt.:


> 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 (2. Jan 2021)

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.


----------



## derFabi95 (2. Jan 2021)

Ah, ja darauf wollte ich ja hinaus bei der Frage


derFabi95 hat gesagt.:


> Gibt es denn, um den Fehler einzugrenzen, eine Möglichkeit den "Suchpfad" für die persistence.xml zu printen?



In der Jar selbst liegt der PersistenceProvider auch tatsächlich in dem angegebenen Pfad, wie du schon sagst.
Und in /META-INF liegt dann die persistence.xml.


----------



## mihe7 (2. Jan 2021)

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.


----------



## derFabi95 (2. Jan 2021)

mihe7 hat gesagt.:


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


Danke, hab ich mal gemacht.
Scheint wirklich funktioniert zu haben - sind dann da die Versionen inkompatibel oder wie erklärst du dir das?


----------



## mrBrown (2. Jan 2021)

derFabi95 hat gesagt.:


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


----------



## derFabi95 (2. Jan 2021)

Ah, interessant!
Vielen lieben Dank für die Unterstützung und Infos!


----------



## fsicher2016 (20. Mrz 2021)

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.


----------



## kneitzel (20. Mrz 2021)

Hilft Dir da evtl. https://stackoverflow.com/questions...d-in-the-persistence-xml-file-but-not-mapped?
==> Synchronize Class List Aufruf, der da beschrieben wurde. ...


----------



## fsicher2016 (20. Mrz 2021)

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?


----------



## kneitzel (20. Mrz 2021)

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.





						EclipseLink/Examples/JPA/OutsideContainer - Eclipsepedia
					






					wiki.eclipse.org
				



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 (20. Mrz 2021)

Vielen Dank für Deine Hilfe.

Ich bin dem Link gefolgt und gesehen, dass die Struktur der Datei* persistence.xm*l 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.


----------

