ClassCastException error when casting back to original class - java

I have the following code:
public void doJob() {
MyObj s;
for ( Object o : MyObj.all().fetch()) {
s = (MyObj) o; // ClassCastException here
if (!s.fileExists()) {
//Do some stuff
}
}
}
which is throwing this exception:
play.exceptions.JavaExecutionException: models.MyObj cannot be cast to models.MyObj
at play.jobs.Job.call(Job.java:155)
at Invocation.Job(Play!)
Caused by: java.lang.ClassCastException: models.MyObj cannot be cast to models.MyObj
at jobs.OrphanSurveys.doJob(OrphanSurveys.java:18)
at play.jobs.Job.doJobWithResult(Job.java:50)
at play.jobs.Job.call(Job.java:146)
... 1 more
(This method runs inside a Play Job class, if that matters.)
The MyObj.all().fetch() is returning an Iterable of some kind containing all of the MyObj objects in the database. MyObj inherits this method from the Play! Framework's Model class, if that matters. That's why it's returning a list of Objects rather than MyObjs, and I can't change how it works.
So, is there some reason that I can't cast back to MyObj? I can see how there would be some weirdness casting back from an Object, but Java seems to know what the class of the object used to be.
Thanks!

It looks like you have ClassLoader issues. The objects being returned by your fetch() method were loaded in a different ClassLoader than the one being used in the current thread to try and cast.
Try this to confirm. Add the three lines of code to your exising code.
for ( Object o : MyObj.all().fetch()) {
// Check classloaders
System.out.println(o.getClass().getClassLoader());
System.out.println(MyObj.class.getClassLoader());
break;
//
s = (MyObj) o; // ClassCastException here
if (!s.fileExists()) {
//Do some stuff
}
}

I saw a recent post here on StackOverflow that indicated that if two otherwise identical instances of the same class are loaded by different classloaders, you cannot cast between them.
Post in question
Check whether you are not subject to the multiple classloader condition here too.

From your stack trace, apparently, there's some other kinds of entries in your collection.
Use o.getClass().getName() inside your loop to know what is .all().fetch() really returning.
Note: Maybe some model.Survey objects?

Related

java dollar symbol com.package.Foo.$$$.Bar issue

I am doing a webservice call and it responds with model class called Foo. Foo is not extending any other class.
Foo data = call();
I can access all data fields normally. String str = data.getData();
However if I do System.out.println(data.toString());
I am getting back the following output: com.package.Foo.$$$.Bar#2938ac9a
I suspect that web framework is doing some reflection magic around responses and wrapping it with proxy class. Since Bar is extending Foo on application level I can't notice anything and still can access all data I need. But...
Problem:
When I am trying to serialise Foo data; as a result I am getting a lot of unexpected data and fields.
I wonder if someone can explain me what does $$$ mean in java and how do I convert Bar object back to Foo?
This is typically a wrapper that some library uses to hide their implementation, with auto-generated code. Another instance (slightly different) can be caught while using Hibernate, which relies on the Proxy class from the com.sun.proxy package:
...
at com.sun.proxy.$Proxy38.getSingleResult(Unknown Source) // Who would name its class 'Proxy38' ?
...
See this other SO answer for more details.
You would have to write your own wrapper in order to succeed:
public Foo barToFoo(Bar data) {
Foo foo = new Foo();
foo.name = data.getName();
...
...
return foo;
}
This is one of your safest options. You keep control on the data, you can still access it, you are converting it back to Foo the way you want (and not some tricky conversion or hidden implementation), and you can handle any case you like (null data, exceptions, etc).
EDIT
It should happen automatically. Is there any solution [...] ?
It looks like there are not, unfortunately. There is an overloading solution in C++, but not in Java.

ClassCastException after applying PathProperties

I'm trying to apply some PathProperties to my Finders but I keep getting this error :
[ClassCastException: java.util.ArrayList cannot be cast to com.avaje.ebean.bean.BeanCollection]
It only happens when I have a List<...> called in my PathProperties like so :
PathProperties pathProperties = PathProperties.parse("(*,historique(*))");
List<Devi> test = Devi.find.apply(pathProperties).findList();
Where my Finder is defined like this :
public static Finder<String,Devi> find = new Finder<String,Devi>(Devi.class);
Here, the object Devi is full of public variables, that I am able to call without any issue (the PathProperties "(*)" works), but when I try to access a List of objects inside this object (here, public List<Histo> historique), it won't work. I tried, and I'm also able to access an object within the object, as long as it's not a List.
I'm kinda lost here, I don't know what I did wrong.
According to https://github.com/ebean-orm/ebean/issues/591 , this is a bug triggered by initializing the ArrayList. Without the initialization it will apparently work.

Dynamic Class casting

I'm having a problem with casting in Android.
I'm developing an App that handle multiple devices, and i'm trying to make a dynamic class alocation (i.e, User sets the device and the app instanciate the class according to the user settings)
Here is a Sample code:
String Usr_imput; //name of the class
Class class = Class.forName(Usr_Input);
Object o = class.newInstance();
with that I can't access methods from the Usr_Input Class. The method class.cast(o) should be the solution to my problems but I can't get it to work, does the cast statement stacks?
Isn't it suposed to work if I use:
class.cast(o);
o.Method();
Anyone has experience on that?
Usr_Input o = (Usr_Input)class.newInstance();
from java doc:
cast
public T cast(Object obj)
blahblah..
Returns:
the object after casting, or null if obj is null
From your codes, you didn't catch the return value. class is not a good name either. check the comment above.
class.cast(o);
o.Method();

Obtaining the original Java class while using instanceof and casting

First off, for anyone out there who abhors, detests and despises the instanceof operator, I understand your concerns with it, but am stuck using it. That's because I don't have the authority to completely refactor the way another development team set a project up, so unless I'm missing somethin here, I just don't see any way of avoiding it.
I have a Java POJO that cannot be changed, and allows you to set an Exception as one of its properties:
public class Message {
private Exception exception;
public void setException(Exception exc) {
this.exception = exc;
}
}
Again, I can't change this Message class.
I am writing an error handler method that gets passed a MessageContainer instances, and I need logic to do different things depending on what type of exception was set on the container's Message:
public class ErrorHandler {
public void handle(MessageContainer container) {
Message msg = container.getMessage();
Exception exc = msg.getException();
if(exc instanceof FizzException)
System.out.println("Do x");
else if(exc instanceof BuzzException)
System.out.println("Do y");
else
System.out.println("Do z");
}
}
Again, I can't change the fact that ErrorHandler#handle is passed a MessageContainer and not an injectable Message instance.
So, even though I really don't like to use instanceof, I don't see any other way of accomplishing this logic (but by all means, please make suggestions...as long as they don't involve making changes to Message, MessageContainer, or the handle(MessageContainer) method!).
But even with using instanceof, how does this code even work? Once you pull the Exception out of the Message, I don't think any of the instanceofs will fire, because its cast to an Exception, with no way to detect if it's BuzzException, FizzException, etc. What are my options here? Thanks in advance.
This code will work as expected. During runtime, instanceof statements will compare the actual type of exc, and not just assume this is only an Exception. If the only statement that worked was exc instanceof Exception, instanceof would be totally worthless :)
Another solution (which I would avoid to use) would be to compare fully qualified class names:
String fqcn = exc.getClass().getName();
if (fqcn.equals("com.foo.FizzException") {
// etc.
}
The cast to exception on
Exception exc = msg.getException();
does not erase the exception runtime type. It has merely cast it to a base type. The instanceof will still work. However, if your FizzException extends BuzzException, then you will need to do the instanceof checks in the other order. i.e. check for the most derived type first.
Otherwise, it will go into the base class check clause instead of the derived one.
It's not clear what you want. If the exceptions are all "given" and you can't change their implementations then you can use exception.getClass().getName() to get the class name and, maybe, look it up in a table or whatever to pick your course of action.
If you can change many of the exception implementations have them all implement an interface that provides a "functionality()" method or whatever. If an given Exception object is instanceof MyFunctionalityInterface then cast to MyFunctionalityInterface and call functionality() to have it return the info you need to guide your actions. Then use instanceof or getClass().getName() to manage the Exception classes you can't change.

java.lang.ClassCastException while trying to print container id in jade

I have a code for finding the list of containers from the ams in jade using queryPlatformAction method. I am getting a problem for typecasting the container id while putting the sop statement at the end..
Result result = (Result) content;
List listOfPlatforms = (List) result.getValue();
Iterator iter = listOfPlatforms.iterator();
while (iter.hasNext())
{
ContainerID next = (ContainerID) iter.next();
System.out.println(next.getID());
}
It is throwing an exception to me.
The exception is: java.lang.ClassCastException: jade.util.leap.ArrayList cannot
be cast to java.util.List
please help.
The two types of List are not in the same class hierarchy and therefore cannot be cast between each other, hence a ClassCastException.
The jade.util.leap.List interface is used within JADE to provide a List collection that looks the same between the different back-ends of JADE, but which is actually implemented differently. From the Javadocs, ArrayList only extends Object.
To fix this, declare listOfPlatforms to be of type jade.util.leap.List.

Categories