We have a JIRA Plugin which is using external library.
<!-- Analytical Request Submission Engine --> <dependency> <groupId>com.bssnsoftware.bpm</groupId> <artifactId>bpm-analytical-request-engine</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>
Request Submission Engine provides a factory, which creates RequestForm PoJo. Its interface signature looks like this.
public RequestForm createRequestForm(Task parentTask) throws BPMException;
The created RequestForm PoJo is then available in our Plugin and we can work with it.
Everything fine sofar...
Then we put it into session.
request.getSession().setAttribute("requestForm", requestForm);
And get it out later on another screen.
Object requestFormObject = request.getSession().getAttribute("requestForm"); RequestForm requestForm = (RequestForm) requestFormObject;
the last line causes ClassCastException.
java.lang.ClassCastException: com.bssnsoftware.bpm.ars.model.RequestForm cannot be cast to com.bssnsoftware.bpm.ars.model.RequestForm
Findings:
1. when we dont downcast requestFrom to its Object representation. Everything works fine.
2. as soon we put it into session, we downcast it to Object. Trying to upcast it back to its real class, causes exception.
3. requestFormObject.getClass().getCanonicalName() returns com.bssnsoftware.bpm.ars.model.RequestForm
4. requestFormObject instanceof RequestForm returns true
5. requestFormObject.getClass().getClassLoader().equals(RequestForm.class.getClassLoader()) returns false
It seems, that the the JIRA Plugin and in the Request Submission Engine are using different ClassLoaders to load RequestForm class. This prevents upcasting from object to concrete class instance.
My guess is, this is related to OSGI framework. Maybe Request Submission Engine is in its own bundle with its own classloader, completely separete from the Plugin itself.
Any ideas how to fix or get around this? Can we force the Request Submission Engine use the same classloader as the plugin?
Community moderators have prevented the ability to post new answers.
It's better if you find some other way to track this. If you absolutely must put it in the session, then it may help to explicitly serialize it to a byte[] (using ObjectOutputStream around a ByteArrayOutputStream) before placing it into the session and deserializing it (using ObjectInputStream around a ByteArrayInputStream) on the way out. This assumes, of course, that RequestForm is even serializable. But then, you shouldn't be putting anything that isn't Serializable into the session either.
All that said, it isn't clear how you could run into this problem within a single lifecycle of the plugin just from one request to another. I could see this happening perhaps if you had configured Tomcat to serialize session data, but as JIRA itself also breaks the rule that you shouldn't store non-Serializable data in a session, you would have more going wrong than just your plugin.
We have found a workaround, but we are totaly unhappy with this.
we can copy the RequestForm object by value. We create a new instance manually and copy every field from the RequestForm created by the Factory. Then we can safely down- and upcast it because we have created the new instance with the same class loader.
In this particullar case - this works as a work-around, since a RequestForm doesn't have much to copy.
However, it doesn't fix the problem. We don't like the idea to find ourself in copying every object which comes from a third party library.
I'm keeping the question open. Someone who finds a better way, deserves the bounty.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
One more finding:
the velocity template doesn't care about type safety. We can call methods on requestFormObject from velocity template and it works. We just cannot recast it in java.
I think this is because velocity is calling methods using reflections. Maybe we can do the same in java?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Community moderators have prevented the ability to post new answers.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.