Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/Examples/OSGi/Developing with EclipseLink OSGi in PDE"

(Developing with EclipseLink OSGi in PDE)
m
 
(8 intermediate revisions by one other user not shown)
Line 1: Line 1:
= Developing with EclipseLink OSGi in PDE =
+
The OSGi support provided by EclipseLink is deprecated and has been replaced by the Gemini JPA projectSee the [[Gemini/JPA/Documentation|Gemini documentation]] for examples.
 
+
<pre>
+
NOTE: These instructions apply to the Galileo release.
+
</pre>
+
 
+
EclipseLink is the the only comprehensive Java persistence framework that is designed for OSGi.  EclipseLink is available as a set of OSGi bundles that can be used with any OSGi framework.  Support is also available for [[EclipseLink/Examples/OSGi/Equinox Byte Code Weaving|byte code weaving of Entities]] when using Equinox.
+
 
+
This example illustrates how to develop a simple OSGi ''hello database'' application using Eclipse's Plug-in Development Environment (PDE) and EclipseLink.
+
 
+
== Environment Setup ==
+
 
+
* Download Eclipse IDE with PDE
+
** A number of distributions include PDE including the Java EE, RCP, and Classic distributions.
+
** In [http://www.eclipse.org/galileo Galileo], EclipseLink JPA is included in the ''Eclipse IDE for Java EE Developers'' and ''Modeling'' distribution.  If you download either of these distribution you do not need to download EclipseLink; the bundles are in the plugins folder of your Eclipse install.
+
 
+
* Obtain and Install Database driver--we'll used the embedded Apache Derby database in this example
+
** Download Apache Derby (org.apache.derby) bundle from [http://download.eclipse.org/tools/orbit/downloads Orbit].
+
** Place the org.apache.derby bundle into your ECLIPSE_HOME\dropins folder.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-2v2.png]]
+
 
+
* Install EclipseLink JPA--skip if your environment includes EclipseLink
+
** Select Help>Install New Software.. and in the Install dialog select the Galileo update site. 
+
** Select ''EclipseLink JPA'' which is in the ''EclipseRT Target Platform Components'' category.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-1v2.png]]
+
** Review the features you're installing.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-3v2.png]]
+
** After downloading, Eclipse will prompt you to restart.  Restart to complete the install.
+
** Confirm that EclipseLink JPA is installed using the Help>About Eclipse SDK menu and clicking the Installation Details button and Installed Software tab on the About dialog.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-4v2.png]]
+
** Confirm that org.apache.derby bundle is installed using the Help>About Eclipse SDK menu and clicking the Installation Details button and Plug-ins tab on the About dialog.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-10.png]]
+
 
+
== Building a JPA application in OSGi ==
+
Now that the environment is setup, you can proceed to building an application.
+
=== Create a Plug-in Project ===
+
* Use the New>Project dialog to select a new "Plug-in Project" and call it "hello.jpa".  For the target platform select "an OSGi Framework" and "standard" and click Next.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-5.png]]
+
* On the Content panel of the New Project wizard set the Execution Environment to "J2SE-1.5" as JPA requires at least Java 5.
+
* Select "Generate an Activator.." and accept the default Activator class name "hello.jpa.Activator" and click Finish.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-6.png]]
+
 
+
=== Create a JPA Entity ===
+
* Create a new "hello.jpa.Person" class as illustrated below.
+
<source lang="java">
+
package hello.jpa;
+
 
+
public class Person {
+
private int id;
+
private String name;
+
+
public int getId() {
+
return id;
+
}
+
 
+
public String getName() {
+
return name;
+
}
+
public void setName(String name) {
+
this.name = name;
+
}
+
}
+
</source>
+
* We can make Person a JPA Entity by adding few annotations but first we need to adjust the hello.jpa bundle manifest to import JPA's javax.persistence packagesOpen the Manifest.mf and go to the Dependencies tab and add imported package "javax.persistence".<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-7.png]]
+
* Now we can add the JPA annotations we need to our Person.
+
<source lang="java">
+
package hello.jpa;
+
 
+
import javax.persistence.Entity;
+
import javax.persistence.GeneratedValue;
+
import javax.persistence.Id;
+
 
+
@Entity
+
public class Person {
+
@Id
+
@GeneratedValue
+
private int id;
+
private String name;
+
+
public int getId() {
+
return id;
+
}
+
 
+
public String getName() {
+
return name;
+
}
+
public void setName(String name) {
+
this.name = name;
+
}
+
}
+
</source>
+
 
+
=== Create a persistence.xml ===
+
* In your source folder, create a META-INF folder and in that folder create a new persistence.xml file.  The persistence.xml below defines a persistence unit called "hello.jpa" with a single Person Entity along with an Apache Derby embedded database connection.  It instructs EclipseLink to drop and create the tables implied by the Entities in the project and it tweaks the logging level and verbosity.  These and other EclipseLink persistence unit properties are documented on the [[Using_EclipseLink_JPA_Extensions_(ELUG)|Using EclipseLink JPA Extensions]] page of the [[EclipseLink/UserManual|EcilpseLink User Guide]].
+
<source lang="xml">
+
<persistence version="1.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_1_0.xsd">
+
    <persistence-unit name="hello.jpa">
+
        <class>hello.jpa.Person</class>
+
        <properties>
+
            <!-- Embedded Derby Login -->
+
            <property name="eclipselink.target-database" value="Derby"/>
+
            <property name="eclipselink.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
+
            <property name="eclipselink.jdbc.url" value="jdbc:derby:comics;create=true"/>
+
            <property name="eclipselink.jdbc.read-connections.min" value="1"/>
+
            <property name="eclipselink.jdbc.write-connections.min" value="1"/>
+
            <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
+
 
+
            <!-- Database Schema Creation -->
+
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
+
            <property name="eclipselink.ddl-generation.output-mode" value="database"/>
+
 
+
            <!-- Logging Settings -->
+
            <property name="eclipselink.logging.level" value="FINE" />
+
            <property name="eclipselink.logging.thread" value="false" />
+
            <property name="eclipselink.logging.session" value="false" />
+
            <property name="eclipselink.logging.exceptions" value="true" />
+
            <property name="eclipselink.logging.timestamp" value="false"/>           
+
        </properties>
+
    </persistence-unit>
+
</persistence>
+
</source>
+
 
+
Notice that we've told EclipseLink to use org.apache.derby.jdbc.EmbeddedDriver as our driver.  However our bundle doesn't import org.apache.derby.jdbc.  PDE can't detect the missing dependency because it doesn't understand EclipseLink's persistence unit properties.  What we have to do is add an import for org.apache.derby.jdbc to our bundle Manifest.mf as we did previously for javax.persistence.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-8.png]]
+
 
+
=== JPA Client Code ===
+
For this example, we'll put our "application code" in the start() method of our Activator.  This is just standard JPA code as in Java SE.  The complete hello.jpa.Activator
+
<source lang="java">
+
package hello.jpa;
+
 
+
import javax.persistence.EntityManager;
+
import javax.persistence.EntityManagerFactory;
+
import javax.persistence.Persistence;
+
 
+
import org.osgi.framework.BundleActivator;
+
import org.osgi.framework.BundleContext;
+
 
+
public class Activator implements BundleActivator {
+
 
+
public void start(BundleContext context) throws Exception {
+
EntityManagerFactory emf = Persistence
+
.createEntityManagerFactory("hello.jpa");
+
EntityManager em = emf.createEntityManager();
+
em.getTransaction().begin();
+
Person bob = new Person();
+
bob.setName("Bob");
+
em.persist(bob);
+
em.getTransaction().commit();
+
em.close();
+
emf.close();
+
}
+
 
+
public void stop(BundleContext context) throws Exception {
+
}
+
}
+
</source>
+
 
+
=== Declaring your Persistence Unit ===
+
* In your Manifest.mf you need to declare that your bundle provides a persistence unit so it can be found by EclipseLink.  Add the following entry to your Manifest.mf:
+
<pre>
+
JPA-PersistenceUnits: hello.jpa
+
</pre>
+
 
+
== Running your Application ==
+
Now that we have all the code and configuration in place we can create a PDE run configuration for our application.
+
* Select Run>Run Configurations.. to open the Run Configurations dialog.
+
* Select "OSGi Framework" as your run configuration type on the left and create a new configuration named "hello.jpa"
+
* Since this example uses EclipseLink JPA and Apache Derby you'll need to include them and their associated bundles (illustrated below) in your configuration.<br/>[[Image:EclipseLinkExamplesOSGiDeveloping_with_EclipseLink_OSGi_in_PDE-9.png]]
+
* Configure javax.persistence to auto-start at start level 1 and org.eclipse.persistence.jpa to auto-start at level 2.  These bundles each provide OSGi services that must be started before application code.
+
* Configure the hello.jpa bundle to auto-start at the default level, which is 4.
+
* Press the "Validate Bundles" button to ensure you have no unsatisfied bundle dependencies.
+
* Press "Run" to launch your application.
+
=== Understanding the Output ===
+
Let's look at the output produced by running the example.  First we see javax.persistence and org.eclipse.persistence.jpa start their services.
+
<pre>
+
osgi> Persistence bundle starting...
+
Persistence bundle started.
+
ProviderTracker: New service detected...
+
ProviderTracker: Added service org.eclipse.persistence.jpa.osgi.PersistenceProviderOSGi
+
</pre>
+
With logging set to FINE, EclipseLink logs the JPA mappings that are being defaulted.
+
<pre>
+
[EL Config]: The access type for the persistent class [class hello.jpa.Person] is set to [FIELD].
+
[EL Config]: The alias name for the entity class [class hello.jpa.Person] is being defaulted to: Person.
+
[EL Config]: The table name for entity [class hello.jpa.Person] is being defaulted to: PERSON.
+
[EL Config]: The column name for element [private int hello.jpa.Person.id] is being defaulted to: ID.
+
[EL Config]: The column name for element [private java.lang.String hello.jpa.Person.name] is being defaulted to: NAME.
+
[EL Info]: EclipseLink, version: Eclipse Persistence Services - 1.1.2.v20090526-r4309
+
</pre>
+
EclipseLink logs into Derby.
+
<pre>
+
[EL Config]: Connection(21350489)--connecting(DatabaseLogin(
+
platform=>DerbyPlatform
+
user name=> ""
+
datasource URL=> "jdbc:derby:comics;create=true"
+
))
+
[EL Config]: Connection(16426320)--Connected: jdbc:derby:comics
+
User: APP
+
Database: Apache Derby  Version: 10.3.1.4 - (561794)
+
Driver: Apache Derby Embedded JDBC Driver  Version: 10.3.1.4 - (561794)
+
[EL Config]: Connection(24864323)--connecting(DatabaseLogin(
+
platform=>DerbyPlatform
+
user name=> ""
+
datasource URL=> "jdbc:derby:comics;create=true"
+
))
+
[EL Config]: Connection(23376028)--Connected: jdbc:derby:comics
+
User: APP
+
Database: Apache Derby  Version: 10.3.1.4 - (561794)
+
Driver: Apache Derby Embedded JDBC Driver  Version: 10.3.1.4 - (561794)
+
[EL Info]: bundleresource://1.fwk15020296/-hello.jpa login successful
+
</pre>
+
As configured in the persistence.xml, EclipseLink drops and creates the database schema for the persistence unit.  Note that the first time you run your application you may see messages indicating that the as yet non-existent tables cannot be dropped.  The next time you run you will not see these messages.
+
<pre>
+
[EL Fine]: Connection(16426320)--DROP TABLE PERSON
+
[EL Fine]: Connection(16426320)--CREATE TABLE PERSON (ID INTEGER NOT NULL, NAME VARCHAR(255), PRIMARY KEY (ID))
+
[EL Fine]: Connection(16426320)--CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
+
...
+
</pre>
+
We see an INSERT for "Bob", the person we created in our application.
+
<pre>
+
[EL Fine]: Connection(23376028)--INSERT INTO PERSON (ID, NAME) VALUES (?, ?)
+
[EL Fine]: Connection(23376028)-- bind => [1, Bob]
+
</pre>
+
And we see logout messages as we shutdown.
+
<pre>
+
[EL Config]: Connection(16426320)--disconnect
+
[EL Info]: bundleresource://1.fwk15020296/-hello.jpa logout successful
+
[EL Config]: Connection(21350489)--disconnect
+
[EL Config]: Connection(23376028)--disconnect
+
</pre>
+
 
+
=== Shutting Down Equinox ===
+
If you didn't adjust any of the Equinox launch parameters then after your application runs Equinox is still running and the console is ready to take commands in the Eclipse Console view.  If you type "ss" (for short status) in the Console you should see something like:
+
<pre>
+
osgi> ss
+
 
+
Framework is launched.
+
 
+
id State      Bundle
+
0 ACTIVE      org.eclipse.osgi_3.5.0.v20090520
+
1 ACTIVE      hello.jpa_1.0.0.qualifier
+
2 ACTIVE      org.eclipse.persistence.antlr_1.1.2.v20090526-r4309
+
3 ACTIVE      org.eclipse.persistence.asm_1.1.2.v20090526-r4309
+
4 ACTIVE      org.eclipse.persistence.core_1.1.2.v20090526-r4309
+
5 ACTIVE      org.eclipse.persistence.jpa_1.1.2.v20090526-r4309
+
6 ACTIVE      org.apache.derby.core_10.3.1.4
+
7 ACTIVE      javax.persistence_1.99.0
+
 
+
osgi>
+
</pre>
+
You'll need to manually shut down Equinox with the "exit" command.  If you don't, and you try to run your application again you'll get an exception.  This is because the embedded Derby database only allows one process to access it at a time and you still have a running application with it open.  The second or third instance of your application will fail.  So "exit" and you're ready to roll again.
+
If you want Equinox to automatically shut down then go to the Arguments tab of your Run Configuration and change the VM argument osgi.noShutdown to false.
+
<pre>
+
-Dosgi.noShutdown=false
+
</pre>
+

Latest revision as of 13:45, 24 October 2012

The OSGi support provided by EclipseLink is deprecated and has been replaced by the Gemini JPA project. See the Gemini documentation for examples.

Back to the top