3

I am trying to access a webservice from a BlackBerry application that I developed.

However, when running the app I get

" App Error 104 Uncaught: NullPointerException "

I am unable to debug, for some strange reason my debugger auto-closes as soon as I start debugging.

Any suggestions on what could be the reason? I would like to mention that I have received the three .csi signature files from BlackBerry, but whenever I try to sign the application it fails: The Signature information in the code signing register request is not of appropriate length. Could this error be due to signing the application?

This is what I've done so far:

package mypackage;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.rmi.RemoteException;
import java.util.Hashtable;

import javacard.framework.UserException;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.location.Location;
import javax.microedition.location.LocationProvider;

import org.kobjects.base64.Base64;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransport;
import org.xmlpull.v1.XmlPullParserException;

import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.component.pane.TitleView;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.image.Image;
import net.rim.device.api.xml.jaxp.SAXParserImpl;

public class LoginTest extends UiApplication 
{

    public static void main(String[] args)  
    {
         //Create a new instance of the app
         //and start the app on the event thread.

        LoginTest app = new LoginTest();
        app.enterEventDispatcher();
    }

    public LoginTest()
    {
         //Display a new screen.
         pushScreen(new LoginTestScreen());
    }

}

//Create a new screen that extends MainScreen and provides
//behaviour similar to that of other apps.

final class LoginTestScreen extends MainScreen
{
   //declare variables for later use
   private InfoScreen _infoScreen;
   private ObjectChoiceField choiceField;
   private int select;
   BasicEditField username;
   PasswordEditField passwd;
   CheckboxField checkBox1;
   ButtonField loginBtn;

   public LoginTestScreen()
   {
        //Invoke the MainScreen constructor.

        super();

        //Add a screen title.

        setTitle("Track24ELMS");

        LabelField login = new LabelField("ELMS Login", LabelField.FIELD_HCENTER); 
        login.setFont(Font.getDefault().derive(Font.BOLD, 30));
        login.setMargin(10, 0, 20, 0); //To leave some space from top and bottom

        HorizontalFieldManager user = new HorizontalFieldManager();
        user.setMargin(0, 0, 10, 0);
        HorizontalFieldManager pass = new HorizontalFieldManager();
        pass.setMargin(0, 0, 20, 0);
        HorizontalFieldManager checkbox = new HorizontalFieldManager();
        checkbox.setMargin(0, 0, 30, 0);
        HorizontalFieldManager btns = new HorizontalFieldManager(HorizontalFieldManager.FIELD_HCENTER);

        LabelField usernameTxt = new LabelField("Username :");
        LabelField passwordTxt = new LabelField("Password :");

        username = new BasicEditField();
        passwd = new PasswordEditField();

        loginBtn = new ButtonField("Login", ButtonField.CONSUME_CLICK); 
        loginBtn.setChangeListener(new LoginButtonListener());

        checkBox1 = new CheckboxField("Remember me",false);

        user.add(usernameTxt);
        user.add(username);
        pass.add(passwordTxt);
        pass.add(passwd);
        //checkbox.add(checkBox1);
        btns.add(loginBtn);
        add(login);
        add(user);
        add(pass);
        add(checkBox1);
        add(btns);
   }

   private class LoginButtonListener implements FieldChangeListener {
       public void fieldChanged(Field field, int context) {
       //Open a new screen
       String uname = username.getText();
       String pwd = passwd.getText();

       //If there is no input
       if (uname.length() == 0 || pwd.length()==0)
       Dialog.alert("One of the textfield is empty!");
       else 
       {
           final String URL = "http://xxx.xxx.com/xxx/xxx.asmx";
           final String METHOD_NAME = "ValidateCredentials";
           final String NAMESPACE = "http://tempuri.org/";
           final String SOAP_ACTION = NAMESPACE+METHOD_NAME;
           //final String URL = "http://prerel.track24elms.com/Android/T24AndroidLogin.asmx/ValidateCredentials";

           SoapObject resultRequestSOAP = null;
           HttpConnection httpConn = null;
           HttpTransport httpt;
           System.out.println("The username" + uname + "password" + pwd );
           SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
           request.addProperty("Username", "abc");//First parameter is tag name provided by web service
           request.addProperty("Password", "xyz");
           System.out.println("The request is=======" + request.toString());
           SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
           envelope.bodyOut = request;
           envelope.dotNet = true;
           envelope.encodingStyle = SoapSerializationEnvelope.XSD;
           envelope.setOutputSoapObject(request);
           System.out.println("The envelope has the value++++"+ envelope.toString());

           /* URL+  Here you can add paramter so that you can run on device,simulator etc. this will work only for wifi */
           httpt = new HttpTransport(URL+ ";deviceside=true;ConnectionUID=S TCP-WiFi");
           httpt.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
           httpt.debug = true;
           try
           {
               System.out.println("SOAP_ACTION    ==   " + SOAP_ACTION);
               httpt.call(SOAP_ACTION, envelope);
               System.out.println("the tranport" + httpt.toString());
               resultRequestSOAP = (SoapObject) envelope.bodyIn;
               System.out.println("result    ==   " + resultRequestSOAP);            
           }
           catch (IOException e) {
               // TODO Auto-generated catch block
               System.out.println("The exception is IO==" + e.getMessage());
           } catch (XmlPullParserException e) {

               // TODO Auto-generated catch block
               System.out.println("The exception xml parser example==="
                       + e.getMessage());
           }
           System.out.println( resultRequestSOAP);
           if(resultRequestSOAP.equals("credentialaccepted"))
           {
           UiApplication.getUiApplication().pushScreen(new InfoScreen()); //Open a new Screen
           }
           else
           {
               System.out.println("Login details not valid");
           }
         }
      }

   };

   //To display a dialog box when a BlackBerry device user
   //closes the app, override the onClose() method.

   public boolean onClose()
   {
        Dialog.alert("Goodbye!");
        System.exit(0);
        return true;
   }

   //Create a menu item for BlackBerry device users to click to see more 
   //information about the city they select.

   private MenuItem _viewItem = new MenuItem("More Info", 110, 10) 
   {
        public void run() 
        {
             //Store the index of the city the BlackBerry device user selects

             select = choiceField.getSelectedIndex();

             //Display a new screen with information about the
             //city the BlackBerry device user selects

             _infoScreen = new InfoScreen();
             UiApplication.getUiApplication().pushScreen(_infoScreen);
        }
   };

   //Create a menu item for BlackBerry device users to click to close 
   //the app.

   private MenuItem _closeItem = new MenuItem("Close", 200000, 10) 
   {
        public void run()
        {
             onClose();
        }
   };


   //Create an inner class for a new screen that displays
   //information about the city a BlackBerry device user selects.

   private class InfoScreen extends MainScreen
   {
        public InfoScreen() 
        {
             super();

             setTitle("Itinerary");


             LabelField login = new LabelField("Employee Itinerary", LabelField.FIELD_HCENTER); 

             Bitmap bitmap = Bitmap.getBitmapResource("img1.jpg");
             EditField statusMsg = new EditField("Status Message", "Update status here");

        }
   }
}
TNR
  • 6,014
  • 3
  • 30
  • 61
Sarah
  • 1,795
  • 1
  • 18
  • 39
  • 1
    are you testing on emulator or real device? because you don't need to sign applications when using the emulator. – Th0rndike Jul 03 '12 at 10:16
  • I am testing it on the emulator but when I click the login button I get the error I mentioned above. Any help? – Sarah Jul 03 '12 at 11:24
  • 1
    You need to debug further this thing. That error is way too generic. At least try to understand which line is throwing the exception. I have had this kind of exception whenever i deal with a null value, so anything inside your application that can be null can be the error thrower – Th0rndike Jul 03 '12 at 12:07
  • I tried debugging with the break point in the login code. Every line throws an error "Source not found". Be it a string text to read from the EditField, SoapObject, print.ln anything, it gives back "Source not found". What is this supposed to mean?I am struggling on this for weeks. Note: I am unable to debug now. Whenever I try to debug the simulator opens and half way on load it shuts off itself. I am so lost. – Sarah Jul 03 '12 at 12:22
  • There is no folder in my project that contains the .asmx file or the .cs file. I am trying to access the .Net Web Service from my app. Should I be having any of these files in my folder for reference or the URL is good enough for reference? Pardon my questions but this is my first BlackBerry app. – Sarah Jul 03 '12 at 12:25
  • have you tried cleaning up your emulator? – Th0rndike Jul 03 '12 at 12:39
  • Yes I have. I do not know why it has suddenly stopped working. – Sarah Jul 03 '12 at 12:48
  • Hey, I made some progress. The debugger is working again.Updating Device manager might be it. Anyways, I changed my code to navigate to a new window at the end of the web service code to see if it passes through the web service. So it did navigate it to the other window but after 2 secs it threw back the same error. I am trying the debugger to investigate. On the debugger, I cant click on any button on the simulator. There is a pop up that says "Application Error - BlackBerry 9800 Simulator Error inside JVM: Access violation reading from 0x00000027". In eclipse the error is at Thread.run(). – Sarah Jul 03 '12 at 13:29
  • @Sarah you running thread somany times ? – Signare Apr 23 '13 at 09:36
  • Hi Guys, I managed to solve this issue by adding the try catch for the main class load. I believe this question has been opened again by @TNR so it will be best if he can comment and ask questions related to it. – Sarah Apr 24 '13 at 09:15

1 Answers1

2

Code Signing

As Th0rndike said, you don't need to sign code to run in the simulator, so that's not your problem (in the simulator).

Getting the Debugger Working Again

Also, if you're having trouble even setting breakpoints or stepping through your own Java source code, then:

  1. Inside the simulator, delete the application as you would on a normal device.
  2. Restart the simulator.
  3. Try running from Eclipse again. If it still doesn't work:
  4. Inside Eclipse, from the BlackBerry menu, choose Clean Simulator and then the JRE package whose simulator you're using (e.g. 5.0.0, 6.0.0, etc.)
  5. Try running from Eclipse again. If it still doesn't work:
  6. I would try reinstalling Eclipse and the BlackBerry Java plugin (together ... rather than installing a non-BlackBerry Eclipse IDE, and then adding the BlackBerry plugin separately). You can download the full Eclipse + BlackBerry plugin from this site.

Keep in mind that you will not be able to step into Java code that's part of the Java runtime, and RIM libraries. You do not have the Java source for those, only the binary libraries. So, if you have the line of code:

String s1 = "afdafsdasdf";
String substring = s1.substring(0, 10);  // <- can not step IN, can step OVER
MyWidget mw = new MyWidget();
mw.foo();                                // <- can step IN, or OVER

you would not be able to step into the second line, because substring(int,int) is not your code. But, you should be able to step into mw.foo() without seeing the "Source Not Found" errors, assuming MyWidget.java is one of your Java source files.

Finding Where Exceptions are Thrown

If you're running, and having trouble finding out where an uncaught NullPointerException (or other exception) is being thrown, see this answer. Basically, just put this debug code in your main program (e.g. MyApp.java):

public static void main(String[] args)
{
    try {
        Application theApp = new MyApp();
        theApp.enterEventDispatcher();
    } catch (Throwable t) {
        t.printStackTrace();
    }
}

And then, after the Throwable is caught, check the Eclipse Console window for stack trace information, showing where the exception came from. Then, debug again, trying to step into that code, and see what's wrong.

But, getting a functioning debugger is an absolute requirement for productive development. Don't bother with other problems until debugging works for you.

Community
  • 1
  • 1
Nate
  • 30,589
  • 12
  • 76
  • 201