2

I am running this code on the Tomcat server as a Java application.

if(levelMap.get(bssid_a) == null)
    continue;
ArrayList<String> levels_a = new ArrayList<String>();
levels_a = (ArrayList<String>)levelMap.get(bssid_a);

where levelMap is a hashmap defines as:

HashMap<String, ArrayList<String>> levelMap

I am getting this error:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.ArrayList

The same code is working in my Android application, so I am not sure why I am getting this error.

The original function (without type casting, but gives me the same error):

    public EDistance[] getLocation(HashMap<String, ArrayList<String>> levelMap) {

        HashMap<String, CrossProduct> crossProductList_local = new HashMap<String, CrossProduct>();

        LinkedHashSet<String> localList = (LinkedHashSet<String>) globalList.clone();

        Iterator<String> cpItera = localList.iterator();
        long time1 = System.currentTimeMillis();
        // Iterator<String> levelIter = levelMap.keySet().iterator();
        // try {

        while (cpItera.hasNext()) {

            String ssids[] = cpItera.next().split(",");
            String bssid_a = ssids[0];

            if(levelMap.get(bssid_a) == null)
                continue;
            //ArrayList<String> levels_a = new ArrayList<String>();
            ArrayList<String> levels_a = levelMap.get(bssid_a);
            double meanA = mean(levels_a, sampleSize, defaultLevel);

            // Iterator<String> cpIterb = localList.iterator();
            //
            // while(cpIterb.hasNext())
            // {

            String bssid_b = ssids[1];
            // if(bssid_a.equals(bssid_b))
            // continue;
            if(levelMap.get(bssid_b) == null)
                continue;
            //ArrayList<String> levels_b = new ArrayList<String>();
            ArrayList<String> levels_b = levelMap.get(bssid_b);
            double meanB = mean(levels_b, sampleSize, defaultLevel);
............

Here is the stacktrace:

SEVERE: Failed to invoke method distance in class com.fingerprint.core.Calculate: [Ljava.lang.Object; cannot be cast to java.util.ArrayList
org.apache.xmlrpc.common.XmlRpcInvocationException: Failed to invoke method distance in class com.fingerprint.core.Calculate: [Ljava.lang.Object; cannot be cast to java.util.ArrayList
    at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:129)
    at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.execute(ReflectiveXmlRpcHandler.java:106)
    at org.apache.xmlrpc.server.XmlRpcServerWorker.execute(XmlRpcServerWorker.java:46)
    at org.apache.xmlrpc.server.XmlRpcServer.execute(XmlRpcServer.java:86)
    at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:200)
    at org.apache.xmlrpc.webserver.XmlRpcServletServer.execute(XmlRpcServletServer.java:112)
    at org.apache.xmlrpc.webserver.XmlRpcServlet.doPost(XmlRpcServlet.java:196)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.ArrayList
    at com.fingerprint.location.HyperbolicEuclideanDistance.getLocation(HyperbolicEuclideanDistance.java:235)
    at com.fingerprint.core.Calculate.distance(Calculate.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:115)
    ... 24 more
Caused by:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.ArrayList
    at com.fingerprint.location.HyperbolicEuclideanDistance.getLocation(HyperbolicEuclideanDistance.java:235)
    at com.fingerprint.core.Calculate.distance(Calculate.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.invoke(ReflectiveXmlRpcHandler.java:115)
    at org.apache.xmlrpc.server.ReflectiveXmlRpcHandler.execute(ReflectiveXmlRpcHandler.java:106)
    at org.apache.xmlrpc.server.XmlRpcServerWorker.execute(XmlRpcServerWorker.java:46)
    at org.apache.xmlrpc.server.XmlRpcServer.execute(XmlRpcServer.java:86)
    at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:200)
    at org.apache.xmlrpc.webserver.XmlRpcServletServer.execute(XmlRpcServletServer.java:112)
    at org.apache.xmlrpc.webserver.XmlRpcServlet.doPost(XmlRpcServlet.java:196)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

The code calling the XMlRPC method:

public String getLocationXMLRPC(HashMap<String, ArrayList<String>> levelMap, String mapFile) {

    try {
        XMLRPCClient client = new XMLRPCClient("http://172.28.184.222:8080/LocationService/xmlrpc");

        Object[] params = new Object[]{levelMap, mapFile};
        //EDistance retura[] = (EDistance[]) client.callEx("Calculate.distance", params);
        String result = (String) client.callEx("Calculate.distance", params);
        return result;

    } catch (XMLRPCException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

The XMLRPC method that calls the erroneous function:

public String distance(HashMap<String, ArrayList<String>> levelMap, String mapFile)
{
    if(dist == null){
        dist = new HyperbolicEuclideanDistance(mapFile, 3, -130,
                false, "fake.txt");
        System.out.println("New Class created!");
    }
    EDistance[] result =  dist.getLocation(levelMap);

    StringBuilder build = new StringBuilder();

    for (int j = 0; j < result.length; j++) {
        if (result[j] != null)
            build.append(j + ") " + result[j] + "\n");
    }
    return build.toString(); 

}

The code that calls the server:

public String getLocationXMLRPC(HashMap<String, ArrayList<String>> levelMap, String mapFile) {

    try {
        XMLRPCClient client = new XMLRPCClient("http://172.28.184.222:8080/LocationService/xmlrpc");


        String result = (String) client.call("Calculate.distance", levelMap, mapFile);
        return result;

    } catch (XMLRPCException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}
14
  • 1
    levelMap appears to be a HashMap<String, Object[]> not a HashMap<String, ArrayList<String>>. The JVM is not wrong in this situation, but somehow your understanding of your code must be. The reason is buried in code not shown. Commented Jul 14, 2012 at 12:34
  • Please show us, what you put in levelMap. That is the cause for the ClassCastException. Besides it is not necessary to initialize levels_a with an empty ArrayList<String>, if you overwrite it at once. And: You don't have to cast, if levelMap is really declared as you already showed. Commented Jul 14, 2012 at 12:37
  • 1
    @ishan If that is the case, you don't need a cast at all. Show the whole method. Commented Jul 14, 2012 at 12:39
  • 1
    @HovercraftFullOfEels distance must be a method of some class Calculate - if that's not an alias - and is called inside the XMLRPC server. The invalid parameter is set up at the client side. Commented Jul 14, 2012 at 13:04
  • 2
    Maybe it's an issue during marshalling/unmarshalling ? Is XMLRPCClient able of keeping nested class/generics like that ? (I don't know at all this class) Commented Jul 14, 2012 at 13:05

2 Answers 2

2

According to ws-xmlrpc XMLRPC Data-Types a HashMap<String, ArrayList<String>>is not a directly supported parameter type.

From the exception stacktrace you posted one can see that a HashMap<String, Object> made it along the wire to your XMLRPC server. That's obvious as the server needs to invoke the distance method using Java reflection. Doing that, a exception would occur if the parameter is not a HashMap at least. Instead the exception in your trace happens, when retrieving an object from that map. There is a invisible type check at runtime when retrieving and assigning an element from HashMap<String, ArrayList<String>>, and that check fails with the exception you have.

Thus it may be a marshalling problem for your XMLRPC library to pass your parameters. So, as Map<String, List<String>> according to the above documentation should be a valid parameter type though, try to change the distance method's and their callees parameters to that and try again.

If that also fails, think about passing the parameters in another more flat and simple structure.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I flattened the structure by converting the arraylist to a csv string and it worked after that.
0

I ran into a similar issue myself. It appears that ws-xmlrpc converts a List inside another structure to an array, even if the function parameter is specified as a List. So Map[String,List[String]] is converted to Map[String,Object] with Object being an array of String. I solved this by handling the incoming List as an array. In some cases I used instanceof to distinguish between array and List.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.