Negative Array Size Exception
Asked Answered
L

6

6

I'm new to Blackberry and I'm trying to get post a search term to a server in xml. But I keep getting this error Request Failed. Reason Java.lang.NegativeArraySizeException.

I wanted to check if the connection works before I parse the data so from this connection, am expecting to receive the response text in xml. Below is the code:

public void webPost(String word) {
    word = encode (word);
    String responseText;
    try{
        HttpConnection connection = (HttpConnection)Connector.open("http://some url.xml");
        connection.setRequestMethod(HttpConnection.POST);
        connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        String postData = "username=loginapi&password=myapilogin&term="+ word;
        connection.setRequestProperty("Content-Length",Integer.toString(postData.length()));
        connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
        OutputStream requestOut = connection.openOutputStream();
        requestOut.write(postData.getBytes());

        InputStream detailIn = connection.openInputStream();
        byte info[]=new byte[(int)connection.getLength()];
        detailIn.read(info);
        detailIn.close();
        requestOut.close();
        connection.close();
        responseText=new String(info);
        requestSuceeded(requestOut.toString(), responseText);
    }
    catch(Exception ex){
        requestFailed(ex.toString());
    }
}

private void requestSuceeded(String result, String responseText) {
    if(responseText.startsWith("text/xml")) { 
        String strResult = new String(result); 
        synchronized(UiApplication.getEventLock()) { 
            textOutputField.setText(strResult); 
        } 
    } else{ 
        synchronized(UiApplication.getEventLock()) { 
            Dialog.alert("Unknown content type: " + responseText); 
        } 
    } 
} 

public void requestFailed(final String message) { 
    UiApplication.getUiApplication().invokeLater(new Runnable() { 
        public void run() { 
            Dialog.alert("Request failed. Reason: " + message); 
        } 
    }); 
} 

private String encode(String textIn) {
     //encode text for http post
    textIn = textIn.replace(' ','+');
    String textout = "";
    for(int i=0;i< textIn.length();i++){
        char wcai = textIn.charAt(i);
        if(!Character.isDigit(wcai) && !Character.isLowerCase(wcai) && !Character.isUpperCase(wcai) && wcai!='+'){
            switch(wcai){
                case '.':
                case '-':
                case '*':
                case '_':
                    textout = textout+wcai;
                    break;
                default:
                    textout = textout+"%"+Integer.toHexString(wcai).toUpperCase();//=textout.concat("%").concat(Integer.toHexString(wcai));
            }
        }else{
            textout = textout+wcai;//=textout.concat(wcai+"");
        }
    }
    return textout;
}    
Lev answered 26/6, 2012 at 13:2 Comment(1)
Possible duplicate of #5090453Eupepsia
L
1

Found it! I forgot to open the Output Stream connection

requestOut = connection.openOutputStream();

and I introduced ByteArrayOutpuStream which helped me finally display the input stream. I also, changed the way I was sending parameters, and used URLEncodedPostData type instead. Since the server was interpreting my former request as a GET instead of a POST. And all I have to do now is to parse the info coming in.

try{
     connection = (HttpConnection)Connector.open("http://someurl.xml",Connector.READ_WRITE);
     URLEncodedPostData postData = new URLEncodedPostData(URLEncodedPostData.DEFAULT_CHARSET, false);
     postData.append("username", "loginapi");
     postData.append("password", "myapilogin");
     postData.append("term", word);

     connection.setRequestMethod(HttpConnection.POST);
     connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
     connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
     requestOut = connection.openOutputStream();
     requestOut.write(postData.getBytes());
     String contentType = connection.getHeaderField("Content-type"); 
     detailIn = connection.openInputStream();         
     int length = (int) connection.getLength();
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     if(length > 0){
         byte info[] = new byte[length];
         int bytesRead = detailIn.read(info);
         while(bytesRead > 0) { 
             baos.write(info, 0, bytesRead); 
             bytesRead = detailIn.read(info); 
             }
         baos.close();
         connection.close();
         requestSuceeded(baos.toByteArray(), contentType);

         detailIn.read(info);
     }
     else
     {
          System.out.println("Negative array size");
     }
           requestOut.close();
           detailIn.close();
           connection.close();
    }

PS. I posted the above code to help anyone with the same problem.

PPS. I also used Kalai's format and it helped wonderfully.

Lev answered 27/6, 2012 at 11:46 Comment(0)
A
4

connection.getLength() is returning -1.

Before creating info array, check the length of the connection.

int length = (int) connection.getLength();

if(length > 0){
     byte info[]=new byte[length];
     // perform operations

}else{
     System.out.println("Negative array size");
}
Antecedent answered 26/6, 2012 at 13:15 Comment(4)
when you say //perform operations you mean like this right : int length = (int) connection.getLength(); if(length > 0){ byte info[] = new byte[length]; detailIn.read(info); detailIn.close(); requestOut.close(); connection.close(); responseText=new String(info); requestSuceeded(requestOut.toString(),responseText); because i did but now i did not get any response now. @kalaiLev
@Lev Yes. Are u getting any error? Check whether "Negative array size" string is printed or not.Antecedent
Got it! I changed the OutputStream to ByteArrayOutputStream and brought in String contentType = connection.getHeaderField("Content-type"); but now it gives me the terms from the string post data, i mean the data that i posted but not the search results :( any help @Kalai @Jite @AurelienLev
i modified it now and it seems to be making a "get" instead of the "post"Lev
O
2

I'm assuming connection.getLength() returns -1 when you try to initialize your array here:

byte info[]=new byte[(int)connection.getLength()];

And that being the reason for the NegativeArraySizeException.

Osteomalacia answered 26/6, 2012 at 13:7 Comment(0)
P
2

I guess when you do

byte info[]=new byte[(int)connection.getLength()];

InputStream does not know its length, so it returns -1.

see http://www.velocityreviews.com/forums/t143704-inputstream-length.html

Parboil answered 26/6, 2012 at 13:8 Comment(0)
F
1

Ref: http://supportforums.blackberry.com/t5/Java-Development/HttpConnection-set-to-POST-does-not-work/m-p/344946

Ref1: Blackberry send a HTTPPost request

Ref2: http://www.blackberryforums.com/developer-forum/181071-http-post-passing-parameters-urls.html

Something like this:

URLEncodedPostData postData = new URLEncodedPostData(URLEncodedPostData.DEFAULT_CHARSET, true); 
postData.append("name",name); 
Ferocious answered 26/6, 2012 at 14:51 Comment(0)
L
1

Found it! I forgot to open the Output Stream connection

requestOut = connection.openOutputStream();

and I introduced ByteArrayOutpuStream which helped me finally display the input stream. I also, changed the way I was sending parameters, and used URLEncodedPostData type instead. Since the server was interpreting my former request as a GET instead of a POST. And all I have to do now is to parse the info coming in.

try{
     connection = (HttpConnection)Connector.open("http://someurl.xml",Connector.READ_WRITE);
     URLEncodedPostData postData = new URLEncodedPostData(URLEncodedPostData.DEFAULT_CHARSET, false);
     postData.append("username", "loginapi");
     postData.append("password", "myapilogin");
     postData.append("term", word);

     connection.setRequestMethod(HttpConnection.POST);
     connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
     connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
     requestOut = connection.openOutputStream();
     requestOut.write(postData.getBytes());
     String contentType = connection.getHeaderField("Content-type"); 
     detailIn = connection.openInputStream();         
     int length = (int) connection.getLength();
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     if(length > 0){
         byte info[] = new byte[length];
         int bytesRead = detailIn.read(info);
         while(bytesRead > 0) { 
             baos.write(info, 0, bytesRead); 
             bytesRead = detailIn.read(info); 
             }
         baos.close();
         connection.close();
         requestSuceeded(baos.toByteArray(), contentType);

         detailIn.read(info);
     }
     else
     {
          System.out.println("Negative array size");
     }
           requestOut.close();
           detailIn.close();
           connection.close();
    }

PS. I posted the above code to help anyone with the same problem.

PPS. I also used Kalai's format and it helped wonderfully.

Lev answered 27/6, 2012 at 11:46 Comment(0)
G
1

java.lang.NegativeArraySizeException indicates that you are trying to initialize an array with a negative length.

The only code that is initializing is -

byte info[]=new byte[(int)connection.getLength()];

You might want to add a check for length before you initialize the array

Grackle answered 21/11, 2017 at 8:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.