|[eclipselink-users] Bytecode-weaving in equinox/eclipse-rcp-applications|
I was trying to set up bytecode weaving within an eclipse-rcp-application. It was not as straightforward as I thought, so I'd like to share my experiences.
First I checked out the rcp-example from the eclipselink-svn-repository:
svn export http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/org.eclipse.persistence.derby/Next, I downloaded the EclipseLink 2.1.0 M7 zip and placed all contained files into the plugin-dir of my eclipse installation.
I started eclipse and imported the checked-out projects into the workspace. Then I copied the derbyclient.jar into org.eclipse.persistence.derby and replaced the external classpath reference with the local jar. So far so good.
Called "Clean project" and still 45 missing-type-errors to resolve: The problem here is, that Import-Package: javax.persistence;version="[1.99.0,2.0.0)" has obviously an unsatisfiable version range. Although you can still find the interim javax.persistence_2.0_preview.jar in the eclipse-plugins folder, it seems to be not considered here.
After changing the MANIFEST.MF of "org.eclipse.persistence.example.jpa.comics.model.annotated", "org.eclipse.persistence.example.jpa.comics.setup" and "org.eclipse.persistence.example.jpa.rcp.comics" to Import-Package: javax.persistence;version=2.0.0 , all errors are gone.
Next I started the derby-db (bin/startNetworkServer) and ran ComicsExampleDBSetup.launch as described in http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/examples/org.eclipse.persistence.example.jpa.rcp.comics/ReadMe.txt. No luck. This program terminates immediately without any logging output. Looking at the launch configuration, there is hardly any bundle selected (probably due to the fact that in the originating workspace the required bundles were part of the workspace and not part of the target platform). So I add all bundles as described in http://wiki.eclipse.org/EclipseLink/Examples/OSGi/Equinox_Byte_Code_Weaving#Equinox_Configuration. Now the program runs with a lot of debug output and without any errors.
Next step is to make the RCP application run: Launching ComicsRCP.launch brings up a dialog with unsatisfied constraints. So I edited the launch configuration to include all missing imports: org.eclipse.core.databinding.observable, org.eclipse.core.databinding.property, javax.persistence, org.eclipse.persistence.jpa, org.eclipse.persistence.antlr, org.eclipse.persistence.core and org.eclipse.persistence.asm. The RCP application starts up.
Besides from having to edit the launch configurations, this all worked pretty much out of the box :-).
No comes the tough part: Getting bytecode weaving to work.
First I revised "ComicsRCP.launch" to set up the the start order and bundle activations as described in http://wiki.eclipse.org/EclipseLink/Examples/OSGi/Equinox_Byte_Code_Weaving#Equinox_Configuration. I also added "-Dosgi.framework.extensions=org.eclipse.persistence.jpa.equinox.weaving" as a VM-start-parameter.
On starting the RCP application there is now a new validation error saying plug-in "org.eclipse.persistence.jpa.equinox" requires Import-Package "org.eclipse.persistence.jpa.equinox.weaving". Proceeding with OK, the application starts up as before. However, no output of that something has been woven. The litmus test of http://wiki.eclipse.org/EclipseLink/Examples/OSGi/Equinox_Byte_Code_Weaving#Confirming_Byte_Code_Weaving_is_Working confirms my concerns.
So I started to pull in eclipselink bundles into my workspace - first "org.eclipse.persistence.jpa.equinox.weaving". This plugin has a class "WeaverRegistry" were I put a first breakpoint into processClass(...). The breakpoint is hit, however "this.weaverServices" is always empty, so nothing is executed in this method. Later on in this method, you can read System.out.println(name + " woven") , so there must be some output if everything goes right. The variable weaverServices is a list of ServiceReferences of type IWeaver, so there must be someone that is registering IWeaver-services. And there is one: EquinoxInitializer in method registerTransformer(...). This class is in "org.eclipse.persistence.jpa.equinox" (this is a fragment-bundle of "org.eclipse.persistence.jpa"). The manifest of that fragment-bundle contains a line:
JPA-Initializer: org.eclipse.persistence.internal.jpa.deployment.osgi.equinox.EquinoxInitializerSo next I searched for "JPA-Initializer" in the EclipseLink code base. One single hit in class "Activator" in "org.eclipse.persistence.jpa" in method start(BundleContext). This method seems to be work-in-progress. All that is done with "JPA-Initializer" is to get out a debug message. Ironically, the chosen log level is CONFIG, so nothing will be printed out in any case (the default threshold is INFO and at this early stage the log-system is yet to be initialized).
So next I took a look at how the EntityManagerFactory is created in the RCP sample: class "Model" in "org.eclipse.persistence.example.jpa.rcp.comics", method getEntityManagerFactory(). Stepping into the class "PersistenceProvider" you can see two constructors: one default-constructor and one with a String parameter and a helpful comment. Obviously, you have to chose the latter constructor to get weaving to work. But what to provide as parameter "initializerClassName"? From looking at the code, this must be a class of type "JPAInitializer". And, guess what, "EquinoxInitializer" is such a class. So I changed the initialization-code to
emf = new PersistenceProvider("org.eclipse.persistence.internal.jpa.deployment.osgi.equinox.EquinoxInitializer")The application starts up as before, but there is a ClassNotFoundException of EquinoxInitializer at the beginning of the log output. This seems to be a weird eclipse-tooling bug. Refreshing any MANIFEST.MF file in the workspace and the CNFE is gone. But still no weaving in sight.
http://wiki.eclipse.org/EclipseLink/Examples/OSGi/Equinox_Byte_Code_Weaving#Equinox_Configuration says, that weaving has to be turned on explicitly in the persistence.xml. So I put this line into it:
<property name="eclipselink.weaving" value="true"/>Restarting the application, there is now a debug-line saying: org.eclipse.persistence.example.jpa.comics.model.annotated.Issue woven . But there is also an error message in the RCP-application:
java.lang.ClassNotFoundException: org.eclipse.persistence.internal.weaving.PersistenceWeavedSo weaving is obviously working now, but there are still some osgi-classloader issues to be sorted out. Not sure about what might be the correct way, I added several Import-Packages to the "org.eclipse.persistence.example.jpa.comics.model.annotated"-plugin as required by the CNFE-messages: org.eclipse.persistence.descriptors.changetracking, org.eclipse.persistence.indirection, org.eclipse.persistence.internal.descriptors, org.eclipse.persistence.internal.weaving, org.eclipse.persistence.queries, org.eclipse.persistence.sessions. There is no guaranty that there are no more required import-packages.
So finally the applications starts up (after a day of excessive debugging) :-).
So, to cut a long story short: Some things could be changed to improve first user experience:
View this message in context: Bytecode-weaving in equinox/eclipse-rcp-applications
Sent from the EclipseLink - Users mailing list archive at Nabble.com.
Back to the top