tags:

views:

321

answers:

4

Im doing a program in GWT. Here is the snippet where Im having problem

 private String[] populateRSSData() {
  1==>> String[] data = null;
  try {
   new RequestBuilder(RequestBuilder.GET,
     "../database.php?action=populaterss").sendRequest(null,
     new RequestCallback() {

      @Override
      public void onResponseReceived(Request request,
        Response response) {
       2==>> data=response.getText().split("~");
      }

      @Override
      public void onError(Request request, Throwable exception) {
       Window.alert(exception.getMessage());
      }
     });
  } catch (RequestException e) {
   Window.alert(e.getMessage());
  }

  return data;
 }

Now the problem arises that I get an error that the variable 1==>> data should be declared final. But if I declare it as final then i cannot store the datas in 2==>>

The error i get

Cannot refer to a non-final variable data inside an inner class defined in a different method RSS_Manager.java

Please suggest

A: 

You should either make the data variable a class member (if possible), or wrap it with some object declared as final.

Variables used inside local inner classes must be declared as final. See also: http://stackoverflow.com/questions/2764035/question-regarding-the-method-local-innerclasses-accesing-the-local-variables-of/2764130#2764130.

--EDIT--

Tahir Akhtar pointed out something very important. Besides the general points I mentioned, there is a flaw in your design - the callback is used for asynchronous response. The response may arrive long after the method terminates, so the result will not be assigned yet.

Eyal Schneider
A: 

You need to use a different data structure for data which is mutable - you can modify a final variable, but not assign to it. Perhaps a java.util.Vector or similar would suit your needs here.

Edric
+6  A: 

Even if you manage to get over the error, the function will not do what you intend it to do. The callback you are creating will be notified asynchronously of the response received from server while your method populateRSSData() will return immediately.

You need to rethink your design taking the asynchrony into account.

EDIT: see Getting Used to Asynchronous Calls

EDIT: Quote from the above link

The important issue to understand is that that the code that follows the RPC call invocation will be executed while the actual round trip to the server is still in progress. Although the code inside the onSuccess() method is defined inline with the call, it will not be executed until both the calling code returns back to the JavaScript main loop, and the result message from the server returns.

Tahir Akhtar
+1 Tahir is right. Your method will always return null because the result of the async call hasn't been assigned yet... Do what you need to do with data in onResponseReceived() ;)
Bogdan
dint think from that perspective. Thanks Tahir, i need to redesign the structure
Shoaib
+2  A: 

An easy way out - declare data as a list of Strings and make the list final. You can always add elements to final list (you just can`t assign a different list to the final variable).

So for your code:

private String[] populateRSSData() {
  final List<String> data = new ArrayList<String>();
  try {
   new RequestBuilder(RequestBuilder.GET,
     "../database.php?action=populaterss").sendRequest(null,
     new RequestCallback() {

      @Override
      public void onResponseReceived(Request request,
        Response response) {
       data.addAll(Arrays.asList(response.getText().split("~"));
      }

      @Override
      public void onError(Request request, Throwable exception) {
       Window.alert(exception.getMessage());
      }
     });
  } catch (RequestException e) {
   Window.alert(e.getMessage());
  }

  return data.toArray(new String[data.size()]);
}
Andreas_D