Why do I see ClassCastException in Groovy through #Delegate method - spring

I have a class (I'm using the library Glisten) that defines a #Delegate member.
class PendingActionWorkflowImpl implements PendingActionWorkflow, WorkflowOperator<PendingActionWorkflow> {
/***
* The #Delegate transformation makes all the methods from WorkflowOperations
* available to owning class (PendingActionWorkflowImpl)
*/
#Delegate
WorkflowOperations<PendingActionActivities> workflowOperations =
SwfWorkflowOperations.of(PendingActionActivities)
}
When I access a nested member of WorkflowOperations ('activities') i get a ClassCastException however if I access the WorkflowOperations property first, then everything works okay...
Promise<List<String>> promise = promiseFor(activities.fetchPendingActions())
Scratching my head on this one.
Here is the exception for completeness:
Details = org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot
cast object 'com.netflix.glisten.impl.swf.AsyncCaller(interface
com..wf.pending.PendingActionActivities, null,
com.netflix.glisten.impl.swf.AsyncCaller$DynamicActivitiesClientFactory(class
com.amazonaws.services.simpleworkflow.flow.DynamicActivitiesClientImpl))'
with class 'com.netflix.glisten.impl.swf.AsyncCaller' to class
'com..wf.pending.PendingActionActivities' at
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
at
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
at
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
at
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)

Related

Cannot access public method in HazelcastSession

I cannot invoke method in HazelcastSession class. I've obtained object and would like to add attribute via public method. I got this error.
I'm using Kotlin.
How to solve this?
The same attempt in Java
This https://github.com/spring-projects/spring-session/blob/master/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/HazelcastSessionRepository.java#L321 is the definition of HazelcastSessionRepository's inner class HazelcastSession
The definition is basically
public class HazelcastSessionRepository {
final class HazelcastSession {
public void setAttribute(String attributeName, Object attributeValue) {
The inner class (HazelcastSession) isn't visible so you can't access what is inside.

Filtering OSGi services using SlingScriptHelper#getService() method

I want to instantiate a service object in my jsp using sling taglib. In normal scenario where the service class is being implemented by only 1 class, its pretty simple:-
RegistrationService registrationService = sling.getService(RegistrationService.class);
But if the service class has more than 1 implementation classes, then how can we make sure to instantiate object for a particular class.
My java class are like:-
1. Interface: RegistrationService
2. Implementation Class 1:-
#Properties({#Property(name = "datasource", value = "SBWS"})
#Service
public class RegistrationServiceImpl implements RegistrationService{
}
3. Implementation Class 2:-
#Properties({#Property(name = "datasource", value = "SOLR"})
#Service
public class RegistrationServiceImpl implements RegistrationService{
}
How can I make sure that using
RegistrationService registrationService = sling.getService(RegistrationService.class);
in jsp will instantiate service for let say implementation class 1
Use SlingScriptHelper#getServices(...) method, which allows to specify a filter:
RegistrationService[] services = sling.getServices(RegistrationService.class, "(datasource=SBWS)");
if (services.length > 0) {
// services[0] contains your service
}
Getting OSGi service and filtering it via properties is quite low-level stuff, consider moving it from JSP to a Java class.

JSF ManagedProperty not working for class

Sorry for my English. I want to set #ManagedProperty for class TaskBO, but it is not works. TaskMB class:
#ManagedBean(name="taskMB")
#RequestScoped
public class TaskMB implements Serializable {
#ManagedProperty(value="#{TaskBO}")
public TaskBO taskBO;
public TaskBO getTaskBO() {
return this.taskBO;
}
public void setTaskBO(TaskBO taskBO){
this.taskBO = taskBO;
}
//...
}
It prints the error:
javax.servlet.ServletException: Unable to set property taskBO for managed bean taskMB
javax.el.ELException: java.lang.IllegalArgumentException: Cannot convert com.otv.model.bo.TaskBO#6c80b8 of type class $Proxy135 to class com.otv.model.bo.TaskBO
But if I add interface ITaskBO, that it is works:
#ManagedProperty(value="#{TaskBO}")
public ITaskBO taskBO;
public ITaskBO getTaskBO() {
return this.taskBO;
}
public void setTaskBO(ITaskBO taskBO){
this.taskBO = taskBO;
}
Why not work #ManagedProperty with the class TaskBO?
Is best pratice wire interface instead of concrete class to prevent the problem you encountered.
Cannot convert com.otv.model.bo.TaskBO#6c80b8 of type class $Proxy135
to class com.otv.model.bo.TaskBO
Often Spring's managed object are proxied and a java proxy can be casted ONLY to interface and not to concrete class; the error above is generated because:
TaskBO object is managed by Spring and proxied to an object of type $Proxy135 (the real type of your object now is not really concrete class TaskBO but a proxy you can cast to ITaskBO, the $Proxy135)
you are trying to do some like public TaskBO taskBO = (TaskBO)$Proxy135; but cast a proxy to concrete class is impossible
The right way is to write public ITaskBO taskBO = (ITaskBO)$Proxy135; and this works because a proxy can be cast only to interface
Avoid - as much as possible - use of concrete class in favor of interface.
In addiction you can look here if you are mixing configuration how described in linked question.

CDI events and generics

I'm trying to send events and do this generically. I mean - create one abstract base DAO class with generic type and fire the event from its method. This should work for all descendants. This works if I define the exact type, but doesn't - if I use generics. What I mean:
AbstractDAO (with generics - doesn't fire the event):
public abstract class AbstractDAO<T extends Persistable> implements Serializable {
#Inject #PostSaveEvent Event<T> postSaveEvent;
public T saveOrUpdate(T object) throws DatabaseException {
T obj = em.merge(object);
postSaveEvent.fire(obj);
}
}
AbstractDAO (no generics, just simple class cast - fires the event):
public abstract class AbstractDAO<T extends Persistable> implements Serializable {
#Inject #PostSaveEvent Event<Polis> postSaveEvent;
public T saveOrUpdate(T object) throws DatabaseException {
T obj = em.merge(object);
postSaveEvent.fire((Polis)obj);
}
}
PolisDAO class, which extends AbstractDAO and defines the generic type:
#Stateless
#Named
#PolisType
public class PolisDAO extends AbstractDAO<Polis> {
// some methods (saveOrUpdate is not overriden!)
}
My observer class:
#Stateless
#Named
public class ProlongationService {
public void attachProlongationToPolisOnSave(#Observes #PostSaveEvent Polis polis) throws DatabaseException {
// ... DO smth with polis object. This is NOT called in the first case and called in the second
}
THis is very strange for me, as "fire()" method for CDI event should define the event type on runtime, not during compilation or deployment... When I debug, I see, that
postSaveEvent.fire(obj);
from the first sample operates exactly with Polis entity. But no event is fired nevertheless...
Upd. I tried the base generic class, but no luck:
#Inject #PostSaveEvent Event<Persistable> postSaveEvent;
Thanks.
This should, in theory, work, however in practice inspecting the type of generic objects at runtime with Java Reflection is, at times, impossible. This is due to type erasure. IIRC the type of the concrete sub class isn't erased, so it should be possible to reconnect this, but I guess the implementation isn't doing this right now.
File this as a bug in the http://issues.jboss.org/browse/WELD issue tracker (if you are using Weld), with the classes you provide as an example and we can try to fix it.
To work around, try injecting the event into the concrete subclass, and passing it as an argument, or using an accessor method, to get it into the abstract super class.

How to use the Facade.Instance method without object construction?

I only recently completed a unit on software patterns and am now attempting to comprehend the PureMVC framework. One thing has got my stumped however, something which is simple to the gurus here.
I'm attempting to create an instance of the singleton Facade class. In the constructor, the comments state:
This IFacade implementation is a Singleton, so you should not call the constructor directly, but instead call the static Singleton Factory method Facade.Instance
How can you call the instance method when the Facade object has not even been created?
The Facade.Instance method looks like this:
public static IFacade Instance
{
get
{
if (m_instance == null)
{
lock (m_staticSyncRoot)
{
if (m_instance == null) m_instance = new Facade();
}
}
return m_instance;
}
}
You are accessing a static property. Static properties are part of the class definition, not class instances. To access a static member (property, field, method), simply use the class name dot member:
var myFacade = SomeClass.Instance;

Resources