ServiceMix unable to find OSGI data source - java

I've been diving into ServiceMix 5.4.0 and OSGi, and have run across a rather weird behavior with OpenJPA.
I have a data source defined like so:
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/test"/>
<property name="username" value="test"/>
<property name="password" value="test"/>
</bean>
<service interface="javax.sql.DataSource" ref="dataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/test"/>
</service-properties>
</service>
</blueprint>
Using the jndi:names command, I can verify that the data source is visible:
karaf#root> jndi:names
JNDI Name Class Name
osgi:service/jndi org.apache.karaf.jndi.internal.JndiServiceImpl
osgi:service/jdbc/test org.apache.commons.dbcp.BasicDataSource
karaf#root>
My persistence.xml:
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="test" transaction-type="JTA">
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/test)</jta-data-source>
<class>com.example.persistence.security.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="openjpa.jdbc.DBDictionary" value="postgres"/>
<property name="openjpa.Log" value="slf4j"/>
</properties>
</persistence-unit>
</persistence>
I then inject the persistence unit into a DAO class via Blueprint:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0">
<bean id="securityDAO" class="com.example.security.dao.SecurityDAOImpl" init-method="init">
<tx:transaction method="*" value="Required" />
<jpa:context property="entityManager" unitname="test" />
</bean>
<service ref="securityDAO" interface="com.example.security.dao.SecurityDAO">
</service>
</blueprint>
The persistence unit is successfully injected, which I verify in the init-method of the DAO:
public void init() {
if (em==null) {
log.error("Entity manager not found. Check JPA configuration.");
throw new RuntimeException("No EntityManager found");
}
log.info("Started SecurityDAO");
}
After all my diligent work, ServiceMix rewards me with the following cryptic exception when I call my DAO's method from another bean:
....
public void setSecurityDAO (SecurityDAO dao) {
this.dao = dao;
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("userName");
String password = req.getParameter("password");
// Invocation of injected DAO results in exception
User u = dao.authenticateUser(userName, password);
This results in the following:
Caused by: java.lang.RuntimeException: The DataSource osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/test) required by bundle persistence/0.0.1.SNAPSHOT could not be found.
at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:87)
at org.apache.aries.jpa.container.unit.impl.DelayedLookupDataSource.getConnection(DelayedLookupDataSource.java:36)
at org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:116)
at org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:93)
at org.apache.openjpa.jdbc.schema.DataSourceFactory.installDBDictionary(DataSourceFactory.java:233)
... 54 more
Caused by: javax.naming.NoInitialContextException: Unable to find the InitialContextFactory org.eclipse.jetty.jndi.InitialContextFactory.
at org.apache.aries.jndi.ContextHelper.getInitialContext(ContextHelper.java:148)
at org.apache.aries.jndi.OSGiInitialContextFactoryBuilder.getInitialContext(OSGiInitialContextFactoryBuilder.java:49)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:216)
at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:64)
... 58 more
Somehow the OSGi-exported data source is not finding its way into the persistence bundle. The strange part is that when I added the following code to the init-method to see if I could execute a test query, not only does OpenJPA not throw an exception in the init method, the invocation of the DAO that was triggering the exception now works as well:
public void init() {
if (em==null) {
log.error("Entity manager not found. Check JPA configuration.");
throw new RuntimeException("No EntityManager found");
}
try {
Query q = em.createNativeQuery("SELECT 1=1");
q.getFirstResult();
} catch (Exception ex) {
log.error("Unable to execute test query against database", ex);
throw new RuntimeException(ex);
}
log.info("Started SecurityDAO");
}
So, to summarize: If I call a method from a different bundle than my DAO, OpenJPA throws an exception indicating that it can't find the InitialNamingContext, and does not show any indication in the log that it has started. If I execute a query inside my DAO before an external component calls into it, somehow OpenJPA is able to find the InitialNamingContext, OpenJPA shows up in the log, and subsequent invocations from outside the DAO bundle begin to work.
Obviously, I'm missing something basic here. Any help or thoughtful explanation of what's breaking, or what I'm doing wrong, will be greatly appreciated.
EDIT:
I hadn't noticed last night, but when I added in the test query, the following lines appear in the log. They are absent when I comment out that query:
... | Runtime | 220 - org.apache.openjpa - 2.3.0 | Starting OpenJPA 2.3.0
... | JDBC | 220 - org.apache.openjpa - 2.3.0 | Using dictionary class "org.apache.openjpa.jdbc.sql.PostgresDictionary".
... | JDBC | 220 - org.apache.openjpa - 2.3.0 | Connected to PostgreSQL version 9.9 using JDBC driver PostgreSQL Native Driver version PostgreSQL 9.3 JDBC4.1 (build 1102).
EDIT 2:
Tried it on plain vanilla Karaf 3.0.3, and got the same error. As a workaround, I created a separate bean in the bundle that executes the above-mentioned test query. Apparently, as long as a single bean in the bundle makes a call to OpenJPA before a bean outside the bundle tries to make a call, OpenJPA will be correctly initialized.
Since this is mentioned nowhere I can see in the OpenJPA/ServiceMix docs, I can only presume that I'm doing something wrong elsewhere in my configuration.
EDIT 3:
Per John Forth, here is the MANIFEST.MF
Manifest-Version: 1.0
Bnd-LastModified: 1430533396366
Build-Jdk: 1.8.0_45
Built-By: somedude
Bundle-Blueprint: OSGI-INF/blueprint/blueprint.xml
Bundle-Description: Database access layer for Peer Review product
Bundle-ManifestVersion: 2
Bundle-Name: Example :: Persistence
Bundle-SymbolicName: persistence-jpa
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: com.example.persistence.security;version="0.0.1.SNAPSHOT",co
m.example.security.dao;version="0.0.1.SNAPSHOT";uses:="com.example.persistence.
security,javax.persistence"
Export-Service: com.example.security.dao.SecurityDAO
Import-Package: javax.persistence;version="[1.1,2)",org.osgi.service.blu
eprint;version="[1.0.0,2.0.0)",org.slf4j;version="[1.7,2)"
Meta-Persistence: META-INF/persistence.xml
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Tool: Bnd-2.3.0.201405100607
And, since it may be related, the pom.xml of the JPA bundle:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>example</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>persistence-jpa</artifactId>
<packaging>bundle</packaging>
<name>Example :: Persistence</name>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Import-Package>*</Import-Package>
<Export-Package>com.example.persistence*,com.example.security.*;version=${project.version}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

If you are using OSGI the class visibility is defined in the MANIFEST.MF files.
Thus the persistence bundle can only see and load classes which are imported in its MANIFEST.MF.
A proper way to extend an existing bundle is to define a fragment which is attached to the existing bundle. This way you can provide classes (e.g. DAOs) and files (e.g. persistence.xml) and make the visible to the fragment-host.
The MANIFEST.MF then looks like
Bundle-ManifestVersion: 2
Bundle-Name: foo.bar.openjpa-fragment
Bundle-SymbolicName: foo.bar.openjpa-fragment;singleton:=true
Bundle-Version: 0.0.1.SNAPSHOT
Bundle-Vendor: foo bar
Fragment-Host: org.apache.openjpa-bundle
Bundle-ClassPath: .
Note that this is only an example.
OSGI means to provide proper visibility.
You can add more than one fragment to an existing bundle, e.g. to keep the configuration in a separate bundle, wich makes it easier to switch the configuration.

Related

Can not obtain connection to DB using JPA - derby embedded driver class missing

I am trying to create local derby database using jpa. As JPA implementation i am using openjpa and as sql implementation derby.
This is persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd">
<persistence-unit name="DataLayer"
transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>DataSource</non-jta-data-source>
<properties>
<property
name="javax.persistence.schema-generation.database.action"
value="create" />
<property name="javax.persistence.jdbc.driver"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:derby:testdb" />
</properties>
</persistence-unit>
</persistence>
This is my main:
public static void main(String[] args)
{
Persistence.generateSchema("DataLayer", null);
EntityManagerFactory factory = Persistence.createEntityManagerFactory("DataLayer");
EntityManager manager = factory.createEntityManager(); // <- Exception here
}
This is starting part of exception i get:
Exception in thread "main" <openjpa-3.1.2-r66d2a72 nonfatal general error> org.a
pache.openjpa.persistence.PersistenceException: There were errors initializing y
our configuration: <openjpa-3.1.2-r66d2a72 fatal user error> org.apache.openjpa.
util.UserException: A connection could not be obtained for driver class "org.apa
che.derby.jdbc.EmbeddedDriver" and URL "jdbc:derby:testdb". You may have spe
cified an invalid URL.
...
saying that i may have specified an invalid URL.
Complete stack trace: https://justpaste.it/3kmgo
Root exception: java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver
I have specified EmbeddedDriver in persistence.xml, also included Maven dependency.
Also i think my connection url and driver is correct according to docs about derby:
https://db.apache.org/derby/docs/10.15/devguide/rdevdvlp22102.html#rdevdvlp22102
https://db.apache.org/derby/docs/10.15/devguide/cdevdvlp40653.html
Dependencies included (using Maven):
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.15.2.0</version>
</dependency>
I tried to change property javax.persistence.jdbc.url to jdbc:derby:testdb;create=true, but same exception. Also tried to set javax.persistence.schema-generation.database.action property to none.
Found out that org.apache.derby.jdbc.EmbeddedDriver class is not in derby artifactid dependency (it has derby and derbyshared jar's). It is in derbytools, so including derbytools to dependencies solve issue abbout missing EmbeddedDriver class:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.15.2.0</version>
</dependency>
Using Debry 10.15.2.0 the Embedded driver is located in Derbytools.jar. Thus must be in your libraries and classpath. Created a new driver(I'd deleted any drivers that say anything Embedded). In the Services tab right click Drivers and Create New. Add Derbytools.jar Highlight it and click the Find Button. Give it a meaningful name and it works as expected. Just to be sure I also added Derby.jar and DerbyShared.jar to avoid problems.

Entities not being detected when using packaged Hibernate JPA persistence provider

Im deploying my web application on a local wildfly-11.0.0.Final
server.
Wildfly however provides its own hibernate and jpa modules which I
dont want to use. I want to use the jpa jars packaged with my
application.
As described in
https://docs.jboss.org/author/display/WFLY10/JPA+Reference+Guide#JPAReferenceGuide-PackagingtheHibernateJPApersistenceproviderwithyourapplication
I added the line
<property name="jboss.as.jpa.providerModule" value="application"/>
to my persistence.xml
Now however my entites (Annotated with #Entity) are not being detected anymore and I have to explicitly name them in my persistence.xml like
<class>com.mycompany.mywebapp.Actor</class>
Is there any way to fix this?
I tried
<jar-file></jar-file>
and
<property name="hibernate.archive.autodetection" value="class, hbm"/>
without success.
My persistence.xml looks like this:
<?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="com.mycompany_mywebapp_war_1.0PU" transaction-type="JTA">
<jta-data-source>java:/jboss/sakila</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="jboss.as.jpa.providerModule" value="application"/>
</properties>
</persistence-unit>
</persistence>
Edit:
Im using hibernate 5.3.7.Final which implements jpa 2.2.
My wildfly server provides hibernate 5.1.10.Final with jpa 2.1.
Edit 2:
I noticed that even though the hibernate version is now 5.3.7.Final the jpa provided by wildfly (specification version 2.1) is still being used which may be causing this issue.
I tried disabling the wildfly modules in a jboss-deployment-structure.xml:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.hibernate" />
<module name="javax.persistence.api" />
</exclusions>
</deployment>
</jboss-deployment-structure>
However now im facing following error:
Cannot upload deployment: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"webapp-1.0.war\".FIRST_MODULE_USE" => "WFLYSRV0153: Failed to process phase FIRST_MODULE_USE of deployment \"webapp-1.0.war\" Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYJPA0019: Could not deploy application packaged persistence provider 'org.hibernate.jpa.HibernatePersistenceProvider' Caused by: java.lang.ClassCastException: class org.hibernate.jpa.HibernatePersistenceProvider"}}
Edit 3:
To test whether this is the cause for my initial problem I manually replaced the jpa jar. Unfortunately this doesnt solve my problem.
Anyway I would like to know how I can fix the issue of my packaged jpa jar not being used and how to make my entities be automatically detected again. Any hints?

EclipseLink: Entities not loaded

I have a JPA-Project, which I'm trying to update to JPA 2.2.0 and EclipseLink 5.7.1 since I ran into bug 429992 of EclipseLink. With the new versions in place, I'm not able to execute my application anymore – EclipseLink throws an exception similar to the following (Short variant from my example below):
[EL Warning]: metamodel: 2018-06-20 22:38:14.1--Thread(Thread[main,5,main])--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
[...]
Exception in thread "main" java.lang.IllegalArgumentException: Object: Artifact#17d919b6 is not a known Entity type.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4324)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:593)
at Main.main(Main.java:12)
Before the update, everything worked fine (besides the aforementioned bug), and also if I checkout an earlier commit, there are no problems.
I have reproduced this behaviour with the minimal setup attached below.
The project is compiled using Java SE 10, as IDE I'm using Eclipse, but in my project properties, I only have the option to select "Generic 2.1" as JPA-Platform. May this be an problem?
Are you able to reproduce this error?
As far as I can see, the Entity-class is listed in the persistence.xml and also annotated with #Entity, but not loaded by EclipseLink. Cleaning the project or even creating a new one does not solve the problem.
Do you have an idea, what my mistake might be? Am I missing any fundamental point about the usage of JPA 2.2/EclipseLink 2.7.1?
Thank you for any hints or comments!
main method in the main class:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Example");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Artifact artifact = new Artifact();
entityManager.persist(artifact);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
Entity Artifact:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
#Entity
#NamedQuery(name = "Artifact.findAll", query = "SELECT a FROM Artifact a")
public class Artifact {
private int id;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
}
persistence.xml:
<?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="Example">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>Artifact</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:./inventory;create=true"/>
<property name="javax.persistence.jdbc.user" value="APP"/>
<property name="javax.persistence.jdbc.password" value="APP"/>
<property name="eclipselink.logging.level" value="FINEST"/>
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
</properties>
</persistence-unit>
</persistence>
pom.xml for Maven dependencies:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JPATest</groupId>
<artifactId>JPATest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/javax.persistence -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/eclipselink -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
</dependencies>
</project>
I had the same problem too. finally, it was solved with an update in pom.xml.
Eclipselink 2.7.1 version has some bugs that fixed at newer versions.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.1</version>
</dependency>
to
<version>2.7.5</version>
before the update, entities are not loaded and em.getMetamodel() was empty.
after the update, all of my entities are loaded successfully
issues and the fixed bugs can be accessed from this link.
I have pretty much the same environment and experience the same problem. I hardly dare to say but in eclipse a "project/maven/update project ..." helped (so far).

What's the right way to use Wildfly 10 with Hibernate and MongoDB?

I'm new to this, did a lot of research now and still I'm not able to develop a working Wildfly / Hibernate / MongoDB Environment.
Here is basically did so far:
Read this Guide
Download Wildfly 10
Download Hibernate OGM 5.1.0.Final and ORM 5.1.4 Modules Archive
Extract Modules into wildfly/modules
Download/Install MongoDB (i tried 2 Versions)
via Brew on Mac
via Ubuntu in an VM
Create new Maven Web Project in Netbeans
Next Step is to edit pom.xml, jboss-deployment-structure.xml, persistence.xml. And that's the Point where the trouble begins. I tried different entries and get different errors. Right now my configuration looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.hibernate.ogm" slot="5.1" services="export" />
<module name="org.hibernate.ogm.mongodb" slot="5.1" services="export" />
</dependencies>
</deployment>
</jboss-deployment-structure>
I saw different Versions of this file, sometimes with slot="main", sometimes with services="import".
Persitence.xml
<?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="comic-PU" transaction-type="JTA">
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="jboss.as.jpa.providerModule" value="org.hibernate:5.1"/>
<property name="hibernate.ogm.datastore.provider" value="mongodb"/>
<property name="hibernate.ogm.datastore.database" value="comicDB"/>
<property name="hibernate.ogm.datastore.host" value="localhost"/>
<property name="hibernate.ogm.datastore.port" value="27017"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
I'am pretty sure here is something wrong. When deploying the Project, Wildfly tries to read persistence.xml, then stuck for a moment and:
20:58:33,255 INFO [org.jboss.as.jpa] (MSC service thread 1-6) WFLYJPA0002: Read persistence.xml for comic-PU
21:03:32,767 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0348: Timeout after [300] seconds waiting for service container stability. Operation will roll back. Step that first updated the service container was 'deploy' at address '[("deployment" => "MYAPP.war")]'
21:03:32,772 ERROR [org.jboss.as.server] (DeploymentScanner-threads - 1) WFLYSRV0022: Deploy of deployment "ComicFeeder-1.0.war" was rolled back with no failure message
Pom.xml is mostly auto-generated, i added
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-core</artifactId>
<version>5.1.0.Final</version>
</dependency>
<archive>
<manifestEntries>
<mode>development</mode>
<url>${project.url}</url>
<Dependencies>org.hibernate.ogm:5.1 services, org.hibernate.ogm.mongodb:5.1 services</Dependencies>
</manifestEntries>
</archive>
Is the manifest entry necessary?
An Errors I got:
Wildfly: org.hibernate.search.engine 5.6.1.Final not found
in wildfly/modules/org/hibernate/search/engine the modules name is "5.6.1.Final-orm51" -> renamed it to 5.6.1.Final, edit the Entry in 5.6.1.Final/modules.xml
Wildfly then starts without that error
This looks like a bug to me
Where is my mistake? What's your "workflow" when you start a new project with hibernate, wildfly and mongodb?
Would it be easier to use Glassfish or any other Server?
Some Tutorials I found are outdated or just did not work (for me).

Persistence.xml and OSGi (Equinox)

I am currently testing out using OSGi. I am running this through Eclipse. I want to have my DAO layer as part of an OSGi solution, but my first stumbling block is this error:
Jun 29, 2009 6:12:37 PM org.hibernate.cfg.annotations.Version <clinit>
INFO: Hibernate Annotations 3.3.0.GA
Jun 29, 2009 6:12:37 PM org.hibernate.ejb.Version <clinit>
INFO: Hibernate EntityManager 3.3.0.GA
Jun 29, 2009 6:12:37 PM org.hibernate.ejb.Ejb3Configuration configure
INFO: Could not find any META-INF/persistence.xml file in the classpath
I have tried putting the persistence.xml file in a lot of different places, to no avail. Any ideas on what I am doing wrong?
Is there a way to manually load the persistence.xml?
The activator looks like this:
package com.activator;
public class PersistenceActivator implements BundleActivator {
#Override
public void start(BundleContext arg0) throws Exception {
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("postgres");
EntityManager em = emf.createEntityManager();
SimpleDaoImpl dao = new SimpleDaoImpl();
dao.setEntityManager(em);
}
#Override
public void stop(BundleContext arg0) throws Exception {
// TODO Auto-generated method stub
}
}
Here is what my directory structure looks like:
alt text http://www.freeimagehosting.net/uploads/7b7b7d2d30.jpg
Here is my Manifest.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Dao Plug-in
Bundle-SymbolicName: Dao
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.4.0"
Bundle-Activator: com.activator.PersistenceActivator
Export-Package: com.dao.service
Require-Bundle: HibernateBundle;bundle-version="1.0.0"
HibernateBundle contains all of the Hibernate and Persistence Jars.
Here is my Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<!-- Sample persistence using PostgreSQL. See postgres.txt. -->
<persistence-unit name="postgres" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<!--
Comment out if schema exists & you don't want the tables dropped.
-->
<property name="hibernate.hbm2ddl.auto" value="create-drop" /> <!-- drop/create tables #startup, drop tables #shutdown -->
<!-- Database Connection Settings -->
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.username" value="postgres" />
<property name="hibernate.connection.password" value="postgres" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/test" />
<!-- Not sure about these... -->
<property name="hibernate.max_fetch_depth">16</property>
<property name="hibernate.jdbc.batch_size">1000</property>
<property name="hibernate.use_outer_join">true</property>
<property name="hibernate.default_batch_fetch_size">500</property>
<!-- Hibernate Query Language (HQL) parser. -->
<property name="hibernate.query.factory_class">
org.hibernate.hql.ast.ASTQueryTranslatorFactory</property>
<!-- Echo all executed SQL to stdout -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">false</property>
<!-- Use c3p0 for the JDBC connection pool -->
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
</properties>
</persistence-unit>
</persistence>
Things I have tried in the Manifest's Classpath with no luck:
Bundle-ClassPath: ., META-INF/persistence.xml
Bundle-ClassPath: ., ../META-INF/persistence.xml
Bundle-ClassPath: ., /META-INF/persistence.xml
Bundle-ClassPath: ., ./META-INF/persistence.xml
Bundle-ClassPath: ., META-INF
Bundle-ClassPath: ., ../META-INF
Bundle-ClassPath: ., /META-INF
Bundle-ClassPath: ., ./META-INF
Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF\persistence.xml
Bundle-ClassPath: ., C:\Workspaces\OSGiJPA\Dao\META-INF
Use EclipseLink and forget about Hibernate and other implementations, because :
You'll have to play with the classloader too much...
Thread.currentThread().setContextClassLoader(...)
You'll be tempted to set the bundle-classpath attribute and add dependencies manually instead of installing jar bundles.
You'll get provider not found errors or you might not be able to find persistence.xml
All the above efforts might not work after many attempts.
However, with EclipseLink it's a no brainer, the implementation was designed to work out of the box in an OSGI environment and there aren't any class loading headaches.
(only a suggestion): Better if you use a lazy loader instead do the job into the activator. For example use a singleton that is invoked into SimpleDaoImpl contructor.
Move META-INF/persistent.xml under src folder (src/META-INF/persistent.xml) because under develop META-INF folder is not in classpath, it works only in runtime mode.
If you are using EclipseLink jpa OSGi, your MANIFEST.MF missing of JPA-PersistenceUnits entry. Add
JPA-PersistenceUnits: postgres
into the MANIFEST.MF.
Then in your launch configuration set the start level of org.eclipse.persistence.jpa.osgi (for ecliselink 2.3.x otherwise org.eclipse.persistence.jpa for 2.1.x) to 2 and start level of javax.persistence to 1.
GOOD LUCK, actually 2.3 has a problem in deployment, doesn't handle bundleresource://xxxx URLs :(, 2.1.2 works very well ;)
I am not using persistence.xml but hibernate.cfg.xml which is similar:
src/main/resource/hibernate/hibernate.cfg.xml
In my Activator I am getting the file via the bundle context:
Here is some example code how I do it and also reference that file:>
private void initHibernate(BundleContext context) {
try {
final AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure(context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml"));
sessionFactory = cfg.buildSessionFactory();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
As you can see line which gets the config file is:
context.getBundle().getEntry("/src/main/resource/hibernate/hibernate.cfg.xml")
As you can see my hibernate.cfg.xml is NOT inside the META-INF folder. It is just in the root folder under /src/......
Hope that helps.
Christoph
You need to have the directory that contains META-INF on the classpath. Each directory is searched for META-INF and if found, then persistence.xml is searched for.
If you put "META-INF" on the classpath, then you'd need another META-INF in that directory.
Try using Bundle-ClassPath like this in your manifest
Bundle-ClassPath: ., /location/of/persistence.xml
The Meta-inf directory is not on the classpath. This should work by simply placing it under your src dirctory. If you want it in a separate location, then you will have to specify the Bundle-Classpath to include that directory. By default the classpath is '.'.
I'm getting the same problem.
I think eclipse link is the best option to use in a OSGi Environment. And there are no problem because you will work basically with the JPA implementation. When you need to move to Hibernate, just replace persintece.xml config and some libs.
you need to set property (for hibernate it will be different):
javax.persistence.provider=org.apache.openjpa.persistence.PersistenceProviderImpl
for call:
Persistence.createEntityManagerFactory(entityManagerFactoryName, properties)
to make it work.
And as mentioned before, you need classloader wrapping. You can use ClassloaderEntityManager from https://issues.apache.org/jira/browse/OPENJPA-1783 to do that.
Regards

Categories