Feature request: Dynamic class enhancement during development compatible with JRebel.
JRebel integration feature
ObjectDB 2 supports dynamic enhancement using a Java Agent.
Please try it and see if it is compatible with JRebel.
I would like to support this ambitious feature request.
I have Netbeans7.1 web applications that will not run when JRebel 4.5.3 is active in combination with objectdb-2.3.7_05 javaagent class enhancement (see part of stacktrace below) but run fine with JRebel disabled. I am a big fan of JRebel "hot deployment" technology:
'JRebel is a JVM-plugin that makes it possible for Java developers to instantly see any code change made to an app without redeploying.'
The JRebel technology is helping to save me months of development time per year, and it helps avoid a lot of frustration, enabling me to develop JSF backing beans and parts of EJBs (such as queries) live and even make changes to some aspects of JPA entities live, instead of waiting for full redeployment of large web applications that take many minutes to fully redeploy. (No, this is not an ad for JRebel, it just is great for my work.)
I invite further expressions of support for compatibility between ObjectDB and JRebel.
Webel
[EDIT: I have not investigated compatibility between JRebel and other ObjectDB enhancement techniques, just javaagent, compile time enhancement may offer a way ahead]
Part of complex stacktrace when running my web application with ObjectDB and JRebel:
INFO: JRebel: Class '$Proxy199' could not be processed by 'org.zeroturnaround.javarebel.integration.util.WeakUtil$WeakClassBytecodeProcessorAdapter@null': *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 INFO: JRebel: Class '$Proxy199' could not be processed by 'org.zeroturnaround.javarebel.integration.util.WeakUtil$WeakClassBytecodeProcessorAdapter@null': *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 INFO: JRebel: Class '$Proxy199' could not be processed by 'org.zeroturnaround.javarebel.integration.util.WeakUtil$WeakClassBytecodeProcessorAdapter@null': *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806 SEVERE: java.lang.StackOverflowError at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1907) at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:727) at org.apache.felix.framework.ModuleImpl.access$400(ModuleImpl.java:71) at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1768) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.println(LoggingOutputStream.java:177) at org.apache.felix.gogo.runtime.threadio.ThreadPrintStream.println(ThreadPrintStream.java:205) at java.lang.Throwable.printStackTrace(Throwable.java:461) at java.lang.Throwable.printStackTrace(Throwable.java:451) at com.zeroturnaround.javarebel.pX.error(JRebel:146) at com.zeroturnaround.javarebel.pX.errorEcho(JRebel:109) at com.zeroturnaround.javarebel.uY.logAndRethrow(JRebel:14) at com.zeroturnaround.javarebel.lk.loadReloadableClass(JRebel:248) at com.zeroturnaround.javarebel.SDKIntegrationImpl.findReloadableClass(JRebel:193) at org.glassfish.web.loader.WebappClassLoader.findClass(WebappClassLoader.java) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1486) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1369) at com.objectdb.o.ACL.loadClass(ACL.java:113) at com.objectdb.o.BCL.loadClass(BCL.java:63) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at com.objectdb.o.SCM.w(SCM.java:453) at com.objectdb.o.JEW.aI(JEW.java:160) at com.objectdb.JEnhancerAgent.transform(JEnhancerAgent.java:154) at org.glassfish.persistence.jpa.ServerProviderContainerContractInfo$1.transform(ServerProviderContainerContractInfo.java:98) at org.glassfish.web.loader.WebappClassLoader$2.preprocess(WebappClassLoader.java:2696) at org.glassfish.web.loader.WebappClassLoader.process(WebappClassLoader.java) at org.zeroturnaround.javarebel.integration.util.WeakUtil$WeakClassBytecodeProcessorAdapter.process(JRebel:210) at com.zeroturnaround.javarebel.SDKIntegrationImpl.processManagedClass(JRebel:501) at com.zeroturnaround.javarebel.sY.a(JRebel:740) at com.zeroturnaround.javarebel.sY.a(JRebel:720) at com.zeroturnaround.javarebel.sY.a(JRebel:709) at com.zeroturnaround.javarebel.lk.processReloadableClass(JRebel:308) at com.zeroturnaround.javarebel.SDKIntegrationImpl.runBytecodeProcessors(JRebel:410) at com.zeroturnaround.javarebel.java4.RuntimeInstall.transform(JRebel:35) at java.lang.ClassLoader.defineClass(ClassLoader.java) at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.zeroturnaround.javarebel.vf.defineRebelClass(JRebel:124) at com.zeroturnaround.javarebel.sY.a(JRebel:691) at com.zeroturnaround.javarebel.lk.a(JRebel:171) at com.zeroturnaround.javarebel.rr.a(JRebel:174) at com.zeroturnaround.javarebel.lk.loadReloadableClass(JRebel:213) at com.zeroturnaround.javarebel.SDKIntegrationImpl.findReloadableClass(JRebel:193) at org.glassfish.web.loader.WebappClassLoader.findClass(WebappClassLoader.java) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1486) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1369) at com.objectdb.o.RCL.j(RCL.java:299) at com.objectdb.o.ACL.loadClass(ACL.java:101) at com.objectdb.o.BCL.loadClass(BCL.java:63)
@dmoshal and ObjectDB users
Announcement of improved compatibility of JRebel with ObjectDB
I have been working in earnest on reporting compatibility problems between JRebel and ObjectDB to the JRebel team at ZeroTurnaround, and I am pleased to report that they have fixed a number of problems for me that were preventing me from sensibly using JRebel with ObjectDB on my main web app.
It's not perfect, and I won't report specifics of individual issues here, suffice it to say I am getting a high level of hot reloading and a significant reduction in re-deployments, for the first time in years (I had tried JRebel many times before but the clashes with ObjectDB had always been a major blocker for me). No longer.
I can use JRebel nightly build and latest ObjectDB together on a very complex web app on Payara41 community server (which is forked from Glassfish).
Thank you (and thanks to the JRebel team) for working on this issue and finding a solution.
Class loading in Java is sometimes very tricky, so unfortnately a collision between two software pieces that make intensive use of class loading can happen. Good to hear that JRebel and ObjectDB can work together now.