Is ReferentialJDOStateManager not used in DataNucleus 4.x? - datanucleus

I'm working with Apache Isis, attempting to update to DN 4.x but have a question about the ReferentialJDOStateManager in DataNucleus.
The JDOStateManager extended this class in DN 3.x but it is not present in DN 4.x
Affected class in Isis -
public class JDOStateManagerForIsis extends ReferentialJDOStateManager implements StateManager, ObjectProvider
I do see this class -
org.datanucleus.state.ReferentialStateManagerImpl
I thought this might be the appropriate replacement, but if I extend ReferentialStateManagerImpl, there are problems...
The problem I encounter when extending the new class -
ReferentialStateManagerImpl extends StateManagerImpl. Which extends
AbstractStateManager<Persistable>
The current JDOStateManagerForIsis is setup to handle PersistenceCapable objects rather than Persistable objects.
I'm not sure where to go from here.

PersistenceCapable is not used by DataNucleus v4.x AFAIK; that was the old JDO-specific bytecode enhancement contract that they no longer use, now using DN-own Persistable.
I also see that each StoreManager can define which StateManager/ObjectProvider it is using, and the RDBMS plugin specifies ReferentialStateManagerImpl

Related

Where does bytecode injection happen?

Motivation
I have a SomeObject.java file:
class SomeObject {
String name;
}
Compiling it creates a bytecode-containing SomeObject.class file.
0xCAFEBABE...
If we use SomeObject on the JVM, it is loaded by the current classloader and all works fine.
Now let's assume that I'd like to have some dynamic code generation. I can write my custom annotation
#Target(ElementType.TYPE)
public #interface Data {
...
}
and add it as a modifier to the class declaration:
#Data
class SomeObject {
String name;
}
I can also retain it for the runtime with #Retention(RetentionPolicy.RUNTIME):
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface Data {
...
}
Question
Where are annotations used for bytecode injection? Does a classloader inject bytecode when loading the class with the appropriate runtime retained annotation like in this figure:
source -(compile)-> bytecode -(classloader bytecode injection)-> injected bytecode -(classloading)-> JVM loaded bytecode
Yes, it would be possible to have your custom classloader to load a class and through bytecode manipulation tools such as Javassist or ASM perform the modifications, loading into memory not the bytecode in the class file but rather the modified one.
Although there are easier (and better, in my opinion) ways of doing it.
Annotation Processor Tool (APT)
Since Java 6 you have APT which allows you to hook into the compiling process (via -processor argument in javac). With APT you have access to the code's AST (Abstract Syntax Tree) and you can perform modifications directly when compiling using the javax.lang.model. This means that your class file will be generated with the needed modifications.
In this case the chain would be something like something like:
source -(compile and performs modifications at model level)-> bytecode already modified - regular class loader -> loads class into memory
Post-Compiling processing
Another approach which can be used is to perform bytecode injection after compilation as a post-compiling process. In this cases you use bytecode modification tools (once again javassist, asm, among others), which can perform the modifications you need when the desired annotation is found, generating a new class file with the injected bytecode.
In such case your chain would be:
source -compile -> bytecode -post-compile-> modified bytecode - regular class loader -> loads class into memory
Runtime modifications
Finally we reach runtime bytecode modifications. Even though your idea is possible, in my opinion I would leave the class loader magic and use tools such has Javassist that also allows you to have dynamic proxies which can be modified and reloaded.
In javassist particular case the chain would be
source -compile -> bytecode -post-compile-> modified bytecode - regular class loader -> loaded into memory - javassist proxy -> modified class - javassist hot swapper -> re-modified class
Proxies aren't perfect though (well nothing is). You'll have a performance hit and you won't be able to modify the public interface of your class (sidenote: both APT and post-compile process can allow you to modify the class public interface). I could go on a bit more on this, but I think this is already enough information to give you food for thought. Feel free to leave a comment if you need additional information.

Gwt Editor framework for interfaces

I am trying to implement gwt editor framework.
I have created a driver as follows:
final Driver driver = GWT.create(Driver.class);
ABC is my class and I am passing object of my ABC class to
driver.edit();
function.
Now instead of class I want to use Interface.
But since we cant create instance of an interface how shall i proceed
for the same?
Can we use interfaces in above mentioned case ?
The Editor framework won't ever instantiate anything (other than its own internal things, of course), so using interfaces is safe, and just like with classes.
Try it, it just works.

Hibernate, Gilead and GWT

I'm experiencing some problems with GWT and Gilead/Hibernate
I did my code according to the tutorial but it fails with
com.google.gwt.user.client.rpc.SerializationException: Type 'ru.atamur.entity.UserEntity_gilead_15' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = ru.atamur.entity.UserEntity_gilead_15#133fa82
Looking at the source code I can see that Gilead transformed my UserEntity into UserEntity_gilead_15 inside GileadRPCHelper.parseReturnValue(returnValue, _beanManager)
I can see that this was deliberately done by ProxyClassMapper (I'm trying to use proxy mode), so I was wondering where Gilead was expecting to tell GWT Serilization mechanism about this new proxy class it introduced ...
Can you share your code ?
before that I want to say that SerializationException is thrown when your class doesn't implement isSerializable interface that you send it to the server.
Every class that you send to the server should implement isSerializable interface

How to use OSGi getServiceReference() right

I am new to OSGi and came across several examples about OSGi services.
For example:
import org.osgi.framework.*;
import org.osgi.service.log.*;
public class MyActivator implements BundleActivator {
public void start(BundleContext context) throws Exception {
ServiceReference logRef =
context.getServiceReference(LogService.class.getName());
}
}
My question is, why do you use
getServiceReference(LogService.class.getName())
instead of
getServiceReference("LogService")
If you use LogService.class.getName() you have to import the Interface. This also means that you have to import the package org.osgi.services.log in your MANIFEST.MF.
Isn't that completely counterproductive if you want to reduce dependencies to push loose coupling? As far as I know one advantage of services is that the service consumer doesn't have to know the service publisher. But if you have to import one specific Interface you clearly have to know who's providing it. By only using a string like "LogService" you would not have to know that the Interface is provided by org.osgi.services.log.LogService.
What am I missing here?
Looks like you've confused implementation and interface
Using the actual interface for the name (and importing the interface , which you'll end up doing anyway) reenforces the interface contract that services are designed around. You don't care about the implemenation of a LogService but you do care about the interface. Every LogService will need to implement the same interface, hence your use of the interface to get the service. For all you know the LogService is really a wrapper around SLF4J provided by some other bundle. All you see is the interface. That's the loose coupling you're looking for. You don't have to ship the interface with every implementation. Leave the interface it's own bundle and have multiple implementations of that interface.
Side note: ServiceTracker is usually easier to use, give it a try!
Added benefits: Using the interface get the class name avoids spelling mistakes, excessive string literals, and makes refactoring much easier.
After you've gotten the ServiceReference, your next couple lines will likely involve this:
Object logSvc = content.getService(logRef)
// What can you do with logSvc now?!? It's an object, mostly useless
// Cast to the interface ... YES! Now you need to import it!
LogSerivce logger = (LogService)logSvc;
logger.log(LogService.LOG_INFO, "Interfaces are a contract between implementation and consumer/user");
If you use the LogService, you're coupled to it anyway. If you write middleware you likely get the name parameterized through some XML file or via an API. And yes, "LogService" will fail terribly, you need to use the fully qualified name: "org.osgi.service.log.LogService". Main reason to use the LogService.class.getName() pattern is to get correct renaming when you refactor your code and minimize spelling errors. The next OSGi API will very likely have:
ServiceReference<S> getServiceReference(Class<S> type)
calls to increase type safety.
Anyway, I would never use these low level API unless you develop middleware. If you actually depend on a concrete class DS is infinitely simpler, and even more when you use it with the bnd annotations (http://enroute.osgi.org/doc/217-ds.html).
#Component
class Xyz implements SomeService {
LogService log;
#Reference
void setLog( LogService log) { this.log = log; }
public void foo() { ... someservice ... }
}
If you develop middleware you get the service classes usually without knowing the actual class, via a string or class object. The OSGi API based on strings is used in those cases because it allows us to be more lazy by not creating a class loader until the last moment in time. I think the biggest mistake we made in OSGi 12 years ago is not to include the DS concepts in the core ... :-(
You cannot use value "LogService"
as a class name to get ServiceReference, because you have to use fully qualified class name
"org.osgi.services.log.LogService".
If you import package this way:
org.osgi.services.log;resolution:=optional
and you use ServiceTracker to track services in BundleActivator.start() method I suggest to use "org.osgi.services.log.LogService" instead of LogService.class.getName() on ServiceTracker initializazion. In this case you'll not get NoClassDefFoundError/ClassNotFountException on bundle start.
As basszero mentioned you should consider to use ServiceTracker. It is fairly easy to use and also supports a much better programming pattern. You must never assume that a ServiceReference you got sometime in the past is still valid. The service the ServiceReference points to might have gone away. The ServiceTracker will automatically notify you when a service is registered or unregistered.

AspectJ problem

Hi I am new to AspectJ and I would like to find out if creating variants of a class using Aspects - I will create another instance of the class as well?
I am guessing that the question is, if I am adding aspects would a new class be created.
The answer is no, as the weaving, either when compiling or at run-time, using AspectJ, will add the changes to the classes that are affected by the aspects, so there is no new class created, it is just that the byte code for the original class and the final class are different.
What do you mean by variants?
If you are asking if AspectJ instantiates copies of your class, the answer is no.
AspectJ uses a design pattern called proxy to intercept calls to your class.