0

I want to load dynamically XML meta-data files that are not in the classpath (the XML meta-data files will be generated after launching my app). I thought I could call the method

MetaDataManager.registerFile(java.lang.String fileURLString, FileMetaData filemd, ClassLoaderResolver clr)

Then, I tried the API enhancement, so I added the following lines:

        JDOEnhancer enhancer = JDOHelper.getEnhancer();
        enhancer.setVerbose(true);          
        enhancer.addClasses(ClassToPersist.class.getName()).enhance();
        getClass().getClassLoader().loadClass(ClassToPersist.class.getName());

The following jars are in the classpath: datanucleus-api-jdo.jar, datanucleus-connectionpool.jar, datanucleus-core.jar datanucleus-rdbms.jar, jdo-api.jar, asm.jar. But when I launch my app, I get this exception:

Caused by: mypackage.MyException:
org.datanucleus.api.jdo.exceptions.ClassNotPersistenceCapableException: The class "mypackage.ClassToPersist" is not persistable. This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found.

Do you please have any idea how to fix this ? PS: I also noticed that the method enhance returns 0 which indicates that the class has not been enhanced (we could exclude the other options)

Thanks

ferjani
  • 89
  • 8
  • if something hasn't been enhanced i'm sure the log would tell you. You did look at the log then ? Also DataNucleus hasn't needed asm.jar and datanucleus-connectionpool.jar for a very long time – Neil Stockton Dec 31 '14 at 18:52
  • Thanks for the tip. I'll check the log Monday (I added asm "as a precaution", it'll be great to remove it) – ferjani Jan 02 '15 at 15:30

2 Answers2

0

So your call to loadClass has loaded the unenhanced class (since it would have been loaded in order to perform the enhancement presumably), and you didn't follow the tutorial that is provided at http://www.datanucleus.org/documentation/development/dynamic_class_metadata_enhance_runtime.html

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
  • Well thanks for the link but the big issue is that the enhancement didn't work. As I already said, the method enhance returns 0 (the number of enhanced classes) – ferjani Jan 02 '15 at 15:28
  • whether enhancement "works" or not you still have to have a separate ClassLoader like this link shows. – Neil Stockton Jan 02 '15 at 17:18
  • So for my information, to use the enhanced class correctly, I have to create an instance of PersistenceManagerFactory using the "updated" classloader. Then, do I need to call the method populateMetaData() twice ? (First before calling enhance, then to persist the data) ? – ferjani Jan 05 '15 at 15:38
  • The link explains it clear enough. You can't use the default class loader since that will have loaded the unenhanced class, and you can't UNLOAD a class once loaded. So you do it in a new class loader. – Neil Stockton Jan 05 '15 at 16:06
  • the link is unavailable – naXa stands with Ukraine Apr 03 '15 at 12:29
  • The link was available when this was posted. It is now updated to the location in the DataNucleus docs – Neil Stockton Apr 03 '15 at 12:37
0

I think I found an easy way to fix this. At runtime, I created a jar that contains the updated metadata file as META-INF/package.jdo. Then I added this jar to the classpath as described here Using this hacks, I didn't need to re-enhace my class since it is enhanced after compilation.

(But for information, I had to call JDOEnhancer.addFiles() to enhance my class.)

Community
  • 1
  • 1
ferjani
  • 89
  • 8