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:
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
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:
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:
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.
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.
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.
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.
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<Map> 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
List<Map> entries = new ArrayList<>();
// 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<Map> 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 );
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?
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.