ClassCastException when retrieving custom object from cache

Hi,
I’m throwing the following exception when attempting to pull a custom object out of cache after successfully storing it:
{
“code”: 0,
“message”: “java.lang.ClassCastException: java.util.HashMap cannot be cast to com.oovoolabs.heystax.restAPI.leaderboard.HeyStaxLeaderboardServiceException”
}
My suspicion is, since I don’t have a data table of the same name and therefore never persist this object, that there’s some sort of mapping issue as a result.
I never attempt to cast the HeyStaxLeaderboard object to a HashMap. This is the code which throws this exception:

if ( Backendless.Cache.contains( "leaderBoard" ) ) {
 HeyStaxLeaderboard cached = Backendless.Cache.get( "leaderBoard", HeyStaxLeaderboard.class );
 List<Map> entries = cached.getEntries();
 return entries;
}

return null;


Am I correct in the assumption that any custom object must also be represented in a data table or am I simply not understanding how the Caching API works?
Based on the provided example code in the documentation, what I’m doing should not throw this exception, reinforced by the fact that I am able to cache this object without issue.
Thanks,
-Ian

Hi Ian,

The caching system is independent of the persistence implementation. You should be able to store any data type in there. I suspect the problem is not with the HeyStaxLeaderboard class, but perhaps with the collection stored within. To see where the failure occurs, you could try one of the following approaches:

  1. Create a local Java program (not a Hosted service) with the same code as the service which stores and retrieves the object in/from cache. This will help you identify where the failure occurs. It could be as basic as:
public class Test
{
 public static void main( String[] args ) throws Throwable
 {
   Backendless.initApp( "app-id", "secret-key", "v1" );
   HeyStaxLeaderboard leaderboard = new HeyStaxLeaderboard();
  // add code to initialize the leaderboard with data
  Backendless.Cache.put( "leaderBoard", leaderboard );
  leaderboard = Backendless.Cache.get( "leaderBoard" );
 }
}

alternatively:

  1. Wrap your current code into one try/catch( Throwable t ) block and log the exception. This will give you an idea where exactly the failure occurs.

Hope this helps.

Regards,
Mark

Mark,
I worked on this last night and today quite a bit and don’t know what else I can try to diagnose this.

Within the execute method of the TimerExtender class, I’m able to store and retrieve the HeyStaxLeaderboard object and its entries collection, which is a List<Map>, without issue.

However, in a hosted API call and in identical local tests (the executing code is exactly the same), I consistently throw this exception when attempting to retrieve a cached item after it is stored by the TimerExtender class.

if ( Backendless.Cache.contains( "leaderBoard" ) )
{
    HeyStaxLeaderboard leaderBoard = Backendless.Cache.get( "leaderBoard", HeyStaxLeaderboard.class );
}

I’ve also tried caching a List<Map> in the cache within the TimerExtender class I’ve written, but consistently throw this exception when attempting to get that stored List<Map> from a method external to the execute method in the TimerExtender class.

Exception in thread “main” java.lang.ClassCastException: [Ljava.util.HashMap; cannot be cast to java.util.List

So, in summary, no issues storing to and retrieving from cache within the TimerExtender class, and same goes for my local tests and the hosted api method (I can store and retrieve from within these methods without issue). However, once I attempt to retrieve something stored in cache by the execute method in my TimerExtender class
from a local test or a hosted API method, I throw the same exception consistently.

It looks as if the exception thrown is being chained as the throwable’s cause is always null, so I can only see a stack trace up to the point where the offending line of code (where the object is retrieved from cache) is executed.

I can provide any code which will help you diagnose this issue.

Thanks,
-Ian

Hi Ian,

I apologize about the inconvenience you’re running into. I’d love to help out with the problem. Please send me the code which demonstrates the problem and we’ll look into it on our side. You can email me directly to mark@backendless.com.

Regards,
Mark

Hey Mark,
Quick update. I was able to get the items out of cache without throwing a ClassCastException like so:

// for brevity's sake, assume a properly populated List&lt;Map&gt; called "entries" is stored in the cache as "leaderBoard" 
// i've verified that the collection is not empty and that the items I expect are properly stored within. 
 
 
 



System.out.println( "Here's what was cached: " ); 
HashMap[] cachedEntries = Backendless.Cache.get( "leaderBoard", HashMap[].class ); 
 
for ( int i = 0; i < cachedEntries.length; i++ ) 
{ 
 System.out.println( cachedEntries[ i ] );  
 
} 
 
 
 
 
 



This is the only way I’m able to get these items back out of cache without throwing that exception. thoughts?
-Ian

Hey Ian,

If I understood you correctly, you have List<Map> going into cache, but on the way out of cache you get HashMap[] ? Please confirm.

Regards,
Mark

That’s precisely it.

List&lt;Map&gt; entries = new ArrayList&lt;&gt;();
// populate the list here


Backendless.Cache.put( "leaderBoard", entries );


// the following throws a ClassCastException for me:
// Exception in thread "main" java.lang.ClassCastException: [Ljava.util.HashMap; cannot be cast to java.util.List
// List&lt;Map&gt; cachedEntries = Backendless.Cache.get( "leaderBoard", List.class );


// the following does NOT throw a ClassCastException.
// from this point I can iterate over this HashMap[]
HashMap[] cachedEntries = Backendless.Cache.get( "leaderBoard", HashMap[].class );

Hi Ian,

The problem is fixed now. You can grab the latest build from here:
https://github.com/Backendless/Android-SDK/tree/master/out

Please let me know if it works for you.

Regards,
Mark

Mark,
I updated the method I wrote for our Hosted API service and used the version of the Backendless SDK you provided to cache the item using the TimerExtender. Both were working fine until an hour or two ago. Has anything changed?

Nothing has changed on our side. Are you getting an error?

Mark,
Yes I’m seeing the same exception again when running the method I wrote to retrieve the cached object. This stopped earlier this morning after using the updated version of the Backendless SDK you linked to, which I used in my TimerExtender project as a lib, to write the object to cache.

Was working great, and now the problem seems to have cropped up again. I’m going to do some more investigation locally to see if there’s something dumb that I overlooked.

The changes we made are strictly in backendless.jar. If you could confirm whether they are working for you in a Java app, we would need to promote that jar to our production environment (it passed all our tests as well).

With the hosted services, event handlers and timers, the jar is provided by the server environment and you cannot override it. I think that explains that you still see the old behavior.

Regards,
Mark

Mark,
Yes, I can confirm the changes fixed that issue for me.

Thanks,
-Ian