Fórumok

ServiceBuilder returning custom class (classloader problem)

thumbnail
Dmitry Fengoff, módosítva 11 év-val korábban

ServiceBuilder returning custom class (classloader problem)

New Member Bejegyzések: 16 Csatlakozás dátuma: 2012.03.19. Legújabb bejegyzések
I have service which should returns custom class (for example MyClass)


public List<myclass> getMyClasses() {
...
}
</myclass>


I put MyClass to WEB-INF/service/com/mypackage/model

If i work with it in current portlet it works correctly. But if I call this method from another portlet i have error:


java.lang.ClassCastException: com.mypackage.model.MyClass cannot be cast to com.mypackage.model.MyClass


I have configured it correctly (move *-service.jar to tomcat/lib/ext and etc.). Moreover with model classes it works correctly from another portlets.
As I understood i need manipulation with *Clp classes. But what is proper way?

How can i fix it?
thumbnail
David H Nebinger, módosítva 11 év-val korábban

RE: ServiceBuilder returning custom class (classloader problem)

Liferay Legend Bejegyzések: 14914 Csatlakozás dátuma: 2006.09.02. Legújabb bejegyzések
Dmitry Fengoff:
How can i fix it?


You really can't. If you dig into the service jar you'll see that those are actually interfaces in the model package, not classes. The implementation classes are left for the plugin's jar.

At runtime when you invoke a normal SB entity method, the service impl code will end up w/ one (or more) implementations of the interface which it will return.

The CLP layer in between takes care of marshalling the object across the class loader boundary between two plugins.

When you have the service jar in both plugins (by packaging the way you did), you actually have two different classes (across the class loader boundary) and cannot cast between them, resulting in the error.

When you moved the service jar to the global lib directory, you ensured that there is only one version of the class that is loaded at the app container level, so it's easier to cross the class loader boundary that way.

Now if you painstakingly go through each part of the SB generated code and re-engineer your custom class so it works the same way, you're probably still going to have issues as there is one (and only one) CLP instance per service jar, and that file gets re-written every time you run service builder (resulting in your hand-coded changes getting lost).
thumbnail
Dmitry Fengoff, módosítva 11 év-val korábban

RE: ServiceBuilder returning custom class (classloader problem)

New Member Bejegyzések: 16 Csatlakozás dátuma: 2012.03.19. Legújabb bejegyzések
Thanks for the answer. I thought as much

For all who will have same problem: now I use workaround in another portlets:


for(Object o : MyService.getMyClasses()) {
    MyClass myObj = new MyClass();
    BeanUtils.copyProperties(myObj, o);
     ....
}


It's like a manipulation as liferay generates in *Clp tier