Following is my main class.
public class ShareData {
/**
* #param args
*/
public static void main(String[] args) {
ShareReader aShareReader = new ShareReader("http://test.com:9000", "dilip.id#gmail.com", "password");
Thread fileThread = new Thread(aShareReader);
fileThread.run(); // fileThread.start() not calling the run() method
}
}
If I type fileThread.run() run method is called. If I call fileThread.start() the run metod is not called. Following is my thread class. I dont know what I am doing wrong.
public class ShareReader implements Runnable {
private String itsShareURL = null;
private String itsUserId = null;
private String itsPassword = null;
private String itsAuthToken = null;
private String itsLoginURL = null;
private String itsChannelUpateURL = null;
/**
*
*/
public ShareReader(String theShareURL, String theUserId, String thePassword) {
this.itsShareURL = theShareURL;
this.itsUserId = theUserId;
this.itsPassword = thePassword;
this.itsLoginURL = itsShareURL + "/v1.0-SNAPSHOT/login";
this.itsChannelUpateURL = itsShareURL + "/v1.0-SNAPSHOT/updateChannelSubscription/";
}
public void run() {
JSONObject json;
JSONArray jsonArray;
itsAuthToken = getToken(itsUserId, itsPassword);
updateChannelList(itsAuthToken);
String aURL = "http://test.com:9000/v1.0-SNAPSHOT/userTimeline/"+itsAuthToken+"/";
try {
String lat = null;
String lon = null;
String udid = null;
String dateTime = null;
String eventID = null;
aEventBean = new EventBean();
jsonArray = readJsonArrayFromUrl(aURL);
for (int i = 0; i < jsonArray.length(); i++) {
json = jsonArray.getJSONObject(i);
lat = json.getString("lat");
lon = json.getString("lon");
udid = json.getString("udid");
eventID = json.getString("eventId");
dateTime = json.getString("dateTime");
aEventBean.setItsLatitude(lat);
aEventBean.setItsLongitude(lon);
aEventBean.setItsUDID(udid);
aEventBean.setItsEventIdentifier(eventID);
aEventBean.setItsDateTime(dateTime);
System.out.println(udid + " ---> " +lat + " ==== " + lon);
sendData(aEventBean);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Sorry If I ask so basic question..
Ideally I need to do fileThread.start() to start a thread..
Thanks in advance...
run() is definitely called if you call start() on fileThread. Check your implementation of run()- its very likely that this method completes or terminates before your check for the print statements. Just an fyi, fileThread.run() is a sequential call while fileThread.start() is a parallel call.
Another vague possibility is that you're not implementing Java's runnable; instead, that may be some custom Runnable class in your project.
EDIT:
So apparently calling fileThread.join() helped you fix your problem, but why does this work? If you call fileThread.join(), the main thread waits until the target (in this case, your fileThread object) terminates.
fileThread.run() never starts a new thread. To start a new thread you have to call fileThread.start().
Related
I am trying to call another async task inside an OnPostExecute. The 2nd task does not run at all it seems. I am unable to print anything from within to the logs.
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject json = new JSONObject(result);
JSONArray lignes = json.getJSONArray("lignes");
populatelist(lignes);
}
catch (JSONException e) {
}
}
}
The populatelist function fills an array. Inside this function, I try to call the 2nd async task to get values based on this list.
protected void populatelist(JSONArray lignes){
try {
for(int i=0;i<lignes.length(); i++) {
JSONObject jsonas = lignes.getJSONObject(i);
String fdesignation = jsonas.getString("designation");
String fqtecde = jsonas.getString("qtecde");
String fcode_produit = jsonas.getString("code");
InfoStock(fcode_produit);
items.add(new PickingListProduitItem(fdesignation,"",fqtecde, ""));
}
}
catch(Exception e){
}
}
InfoStock() is the function that is used to return additional from a web service.
protected void InfoStock(String code_produit){
String stockURL = "http://" + mSharedPreferences.getString(Constants.SERVER_IP,"")+"//rest/v2/produit/info/code/"+ code_produit + "?stock=true";
try {
if (mDownloader != null && mDownloader.getStatus() == AsyncTask.Status.RUNNING) {
mDownloader.cancel(true);
mPDialog.dismiss();
}
mPDialog = new ProgressDialog(getApplicationContext());
mDownloader = new XMLDownloader(getApplicationContext(),mPDialog);
byte[][] downloadResults = mDownloader.execute(stockURL).get();
// Read stock info.
String s = new String(downloadResults[0], StandardCharsets.UTF_8);
JSONObject resp = new JSONObject(s);
PrixStockJSONParser psj = new PrixStockJSONParser(resp);
mRepInfoStock = psj.getRepInfoStock();
mRepInfoPrix = psj.getRepInfoPrix();
} catch (Exception ex) {
}
}
I am trying to set a value in the array <> created in the OnPostExecute Method. However there is no error message and the array is not populated at all. Even if I try to print a log from the InfoStock function, it does nothing.
Any suggestions are welcome.
I am new to using SSE with Jersey, and have the following situation.
I have a JAXB annotated class that represents and acts on the I/O of a Raspberry Pi (class GpioRepresentation).
The client class accesses the status of I/O through the method getUpdate() which returns the XML object
representation of the class.
#XmlRootElement
public class GpioRepresentation implements GpioSubject
{
...
/**
* Returns an object of this class with the current
* representation of the I/O states
* #return this
*/
public synchronized GpioRepresentation getUpdate()
{
this.getGarageDoorInputState();
this.getZoneOneFeedback();
this.getZoneTwoFeedback();
this.getZoneThreeFeedback();
this.getGarageDoorRelayState();
this.getZoneOneRelayState();
this.getZoneTwoRelayState();
this.getZoneThreeRelayState();
return this;
}
...
}
The client that uses getUpdate() is the class HomeResource, method getPiStatusStream(). This is a JAX-RS annotated method,
and provides remote clients Server Sent Events. Currently this method is written as shown here with a continuous loop
in a separate thread which polls for updates.
#Path("/homeservice")
#RolesAllowed({"ADMIN", "USER"})
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.APPLICATION_XML)
public class HomeResource
{
private static final Logger LOGGER = LoggerFactory.getLogger(HomeResource.class);
private GpioRepresentation piService;
...
/**
* gets status information on the Raspberry Pi's
* I/O and returns it to the client on a continuous basis
* and only if it changes.
* #return EventOutput
*/
#GET
#Path("/iostatus")
#Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getPiStatusStream()
{
final EventOutput eventOutput = new EventOutput();
new Thread(new Runnable()
{
public void run()
{
try {
String gdState = null;
String zOneState = null;
String zTwoState = null;
String zThreeState = null;
String gdRState = null;
String zOneRState = null;
String zTwoRState = null;
String zThreeRState = null;
String lastgdState = null;
String lastzOneState = null;
String lastzTwoState = null;
String lastzThreeState = null;
String lastgdRState = null;
String lastzOneRState = null;
String lastzTwoRState = null;
String lastzThreeRState = null;
while(true) {
final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
final GpioRepresentation iostatus = piService.getUpdate();
gdState = piService.getGarageDoorInputState();
zOneState = piService.getZoneOneFeedback();
zTwoState = piService.getZoneTwoFeedback();
zThreeState = piService.getZoneThreeFeedback();
gdRState = piService.getGarageDoorRelayState();
zOneRState = piService.getZoneOneRelayState();
zTwoRState = piService.getZoneTwoRelayState();
zThreeRState = piService.getZoneThreeRelayState();
if (!(gdState.equals(lastgdState) && zOneState.equals(lastzOneState) && zTwoState.equals(lastzTwoState) && zThreeState.equals(lastzThreeState)
&& gdRState.equals(lastgdRState) && zOneRState.equals(lastzOneRState) && zTwoRState.equals(lastzTwoRState) && zThreeRState.equals(lastzThreeRState)))
{
OutboundEvent event = eventBuilder.data(GpioRepresentation.class, iostatus)
.mediaType(MediaType.APPLICATION_XML_TYPE)
.build();
eventOutput.write(event);
lastgdState = gdState;
lastzOneState = zOneState;
lastzTwoState = zTwoState;
lastzThreeState = zThreeState;
lastgdRState = gdRState;
lastzOneRState = zOneRState;
lastzTwoRState = zTwoRState;
lastzThreeRState = zThreeRState;
}
Thread.sleep(100);
}
}
catch (Exception exeption)
{
System.err.println("Error: " + exeption);
}
finally
{
try
{
eventOutput.close();
}
catch (IOException ioClose)
{
throw new RuntimeException("Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
}
...
}
The issue I have and see with this is that this doesn't scale well. Creating a thread for every GET from a remote client
takes time, and eats CPU resources. Plus I don't think this is an elegant solution. What I would like to do
is encapsulate the event code into a separate class, and use some sort of observer pattern that can trigger the
creation of an event....however, how do I tie this into the resource method so that it can be returned to the
remote client?
Can anyone point me to some examples, or provide advice on designing a solution for this?
Solution was to utilize the SseBroadcaster class. I made the HomeService class an observer of the GpioRepresentation class, and then called a new method (broadcastIOUpdateMessage()) which then output my event to the remote client.
public void broadcastIOUpdateMessage()
{
GpioRepresentation iostatus = piService.getUpdate();
OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
OutboundEvent event = eventBuilder.data(GpioRepresentation.class, iostatus)
.mediaType(MediaType.APPLICATION_XML_TYPE)
.build();
broadcaster.broadcast(event);
}
#GET
#Path("/iostatus")
#Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getPiStatusStream()
{
final EventOutput eventOutput = new EventOutput();
this.broadcaster.add(eventOutput);
return eventOutput;
}
Before getting down vote. Yes I read the forums before asking this question. RSSReader Async Task
Read that one above but I still don't get it.
The question:
I wrote een RSSReader in Java. This perfectly works in the console prints what I want etc. But in Android it doesn't work because it's not using een Async Task. Now I understood from the Google Documentation that there are three types to be entered AsyncTask something like that. I have no idea how I can implement this in my code. Do I need to make a seperate class extends it with AsyncTask and create and instance of my Reader and in it's doInBackground method call my reader or how do I need to do this.
This is the code of my RSSReader:
public class RSSReader {
//Lists to store headlines, descriptions & images
String url = "http://www.nu.nl/rss/Algemeen";
List<String> titleList;
List<String> descriptionList;
List<String> imageList;
public RSSReader(){
try {
titleList = readRSS(url, "<title>", "</title>");
descriptionList = listFilter(readRSS(url, "<description>", "</description>"), " ", "");
imageList = readRSS(url, "<enclosure url \"", "\" length=\"0\" type=\"image/jpeg\"</enclosure>");
}
catch (IOException e){
}
}
public List<String> readRSS(String feedUrl, String openTag, String closeTag) throws IOException, MalformedURLException {
URL url = new URL(feedUrl);
BufferedReader reader= new BufferedReader(new InputStreamReader(url.openStream()));
String currentLine;
List<String> tempList = new ArrayList<String>();
while((currentLine = reader.readLine()) != null){
Integer tagEndIndex = 0;
Integer tagStartIndex = 0;
while (tagStartIndex >= 0){
tagStartIndex = currentLine.indexOf(openTag, tagEndIndex);
if(tagStartIndex >= 0){
tagEndIndex = currentLine.indexOf(closeTag, tagStartIndex);
tempList.add(currentLine.substring(tagStartIndex + openTag.length(), tagEndIndex) + "\n");
}
}
}
tempList.remove(0);
return tempList;
}
public List<String> getDesciptionList(){
return descriptionList;
}
public List<String> getTitleList(){
return titleList;
}
public List<String> getImageList(){
return imageList;
}
public List<String> listFilter(List<String> tempList, String require, String
replace){
//Creates new List
List<String> newList = new ArrayList<>();
//Loops through old list and checks for the 'require' variable
for(int i = 0; i < tempList.size(); i++){
if(tempList.get(i).contains(require)){
newList.add(tempList.get(i).replace(require, replace));
}
else{
newList.add(tempList.get(i));
}
}
return newList;
}
}
In RSSReader#readRSS,you do not check tempList.size()
and do not forget add
<uses-permission android:name="android.permission.INTERNET"/>
to your AndroidManifest.xml
for example
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RssReaderAsyncTask(new RSSCallBack() {
#Override
public void success(RSSReader rssReader) {
// TODO That Should run on UI Thread if you update UI
// for example
final RSSReader reader = rssReader;
// you can use runOnUiThread or Handler update UI
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Toast
Toast.makeText(MainActivity.this, reader.getTitleList().toString(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void failed() {
// TODO That Should run on UI Thread if you update UI
Log.e("RSS", "failed");
}
}).execute("");
}
private class RssReaderAsyncTask extends AsyncTask<String, Integer, Integer> {
private RSSCallBack rssCallBack;
public RssReaderAsyncTask(RSSCallBack rssCallBack) {
this.rssCallBack = rssCallBack;
}
#Override
protected Integer doInBackground(String... params) {
// TODO
try {
RSSReader reader = new RSSReader();
rssCallBack.success(reader);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
rssCallBack.failed();
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
rssCallBack.failed();
e.printStackTrace();
}
return null;
}
}
private interface RSSCallBack {
void success(RSSReader rssReader);
void failed();
}
public class RSSReader {
// Lists to store headlines, descriptions & images
String url = "http://www.nu.nl/rss/Algemeen";
List<String> titleList;
List<String> descriptionList;
List<String> imageList;
public RSSReader() throws MalformedURLException, IOException {
titleList = readRSS(url, "<title>", "</title>");
descriptionList = listFilter(readRSS(url, "<description>", "</description>"), " ", "");
imageList = readRSS(url, "<enclosure url \"", "\" length=\"0\" type=\"image/jpeg\"</enclosure>");
}
public List<String> readRSS(String feedUrl, String openTag, String closeTag)
throws IOException, MalformedURLException {
URL url = new URL(feedUrl);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String currentLine;
List<String> tempList = new ArrayList<String>();
while ((currentLine = reader.readLine()) != null) {
Integer tagEndIndex = 0;
Integer tagStartIndex = 0;
while (tagStartIndex >= 0) {
tagStartIndex = currentLine.indexOf(openTag, tagEndIndex);
if (tagStartIndex >= 0) {
tagEndIndex = currentLine.indexOf(closeTag, tagStartIndex);
tempList.add(currentLine.substring(tagStartIndex + openTag.length(), tagEndIndex) + "\n");
}
}
}
if (tempList.size() > 0) {
//TODO you do not check it
tempList.remove(0);
}
return tempList;
}
public List<String> getDesciptionList() {
return descriptionList;
}
public List<String> getTitleList() {
return titleList;
}
public List<String> getImageList() {
return imageList;
}
public List<String> listFilter(List<String> tempList, String require, String replace) {
// Creates new List
List<String> newList = new ArrayList<String>();
// Loops through old list and checks for the 'require' variable
for (int i = 0; i < tempList.size(); i++) {
if (tempList.get(i).contains(require)) {
newList.add(tempList.get(i).replace(require, replace));
} else {
newList.add(tempList.get(i));
}
}
return newList;
}
}
}
You are right, you need Asynctask. But it is too much to explain here, it has already been explained very thoroughly here, so you might wanna take a look:
https://stackoverflow.com/a/9671602/3673616
What you need to make sure is to run your network calls in doInBackground, you can manipulate the UI in onPreExcute and after finish in onpostExecute. For more details please visit the link.
Well i assume that you already know the code so in the doInBackground method should be the long running code, like getting information from internet/server etc. You can then return a string with success or error that will be catched from onPostExecute method, where you can just do what ever you like with the result.
So i would say no need for new class just extend async task in this, implement the 2 methods i mentioned and in the methods call the right function that you already have with just a litttle change for returning result.
This is my first Android App. I'm trying to call a function in a service from a different class i am using foursquare API. I tried this function earlier in an activity and it worked perfectly but in a service im getting a NullPointerException.
This is the code i am using:
public class GuideMeService extends Service implements LocationListener {
LocationManager locationManager;
Geocoder geocoder;
// private CalendarContentResolver Calendar;
public FoursquareApp mFsqApp;
public ArrayList<FsqVenue> mNearbyList;
private static String TAG = "Service Class";
double lat;
double lng;
public static final String[] FIELDS = { CalendarContract.Calendars.NAME,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.CALENDAR_COLOR,
CalendarContract.Calendars.VISIBLE };
public static ArrayList<String> Events = new ArrayList<String>();
public static final Uri CALENDAR_URI = Uri
.parse("content://com.android.calendar/calendars");
public static final Uri EVENTS_URI = Uri
.parse("content://com.android.calendar/events");
private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds
public static String query = "";
Set<String> calendars = new HashSet<String>();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG, "GuideMe Servise started");
//this.stopSelf();
locationManager = (LocationManager)this.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
Events = readCalendarEvent(getApplicationContext());
for(int i = 0 ; i < Events.size() ; i++){
query += Events.toArray()[i].toString() + " ";
}
Thread thread = new Thread()
{
#Override
public void run() {
try {
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
mNearbyList = mFsqApp.SearchBykeyword(location.getLatitude(), location.getLongitude(), query);
}catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
Im getting The error on this line :
mNearbyList = mFsqApp.SearchBykeyword(location.getLatitude(), location.getLongitude(), query);
And this is the function i'm calling in the mFsqApp class:
public ArrayList<FsqVenue> SearchBykeyword(double latitude, double longitude, String query) throws Exception {
ArrayList<FsqVenue> venueList = new ArrayList<FsqVenue>();
try {
String ll = String.valueOf(latitude) + "," + String.valueOf(longitude);
URL url = new URL(API_URL + "/venues/search?ll=" + ll + "&query=" + query + "&radius=" + 50 + "&oauth_token=" + mAccessToken + "&v=20120610");
Log.d(TAG, "Opening URL " + url.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
//urlConnection.setDoOutput(true);
urlConnection.connect();
String response = streamToString(urlConnection.getInputStream());
JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
JSONArray groups = (JSONArray) jsonObj.getJSONObject("response").getJSONArray("groups");
int length = groups.length();
if (length > 0) {
for (int i = 0; i < length; i++) {
JSONObject group = (JSONObject) groups.get(i);
JSONArray items = (JSONArray) group.getJSONArray("items");
int ilength = items.length();
for (int j = 0; j < ilength; j++) {
JSONObject item = (JSONObject) items.get(j);
FsqVenue venue = new FsqVenue();
venue.id = item.getString("id");
venue.name = item.getString("name");
JSONObject location = (JSONObject) item.getJSONObject("location");
Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(Double.valueOf(location.getString("lat")));
loc.setLongitude(Double.valueOf(location.getString("lng")));
venue.location = loc;
//venue.address = location.getString("address");
venue.distance = location.getInt("distance");
//venue.herenow = item.getJSONObject("hereNow").getInt("count");
venue.type = group.getString("type");
venueList.add(venue);
}
}
}
} catch (Exception ex) {
throw ex;
}
return venueList;
}
Updates:
07-08 21:26:18.580: W/System.err(24365): java.lang.NullPointerException
07-08 21:26:18.580: W/System.err(24365): at com.android.guideme.GuideMeService$1.run(GuideMeService.java:86)
You're declaring the (unfortunately public) mFsqApp variable here:
public FoursquareApp mFsqApp;
but you haven't shown any code to assign it a value - so it will have the default value of null, causing a NullPointerException when you dereference it. You need to assign a non-null value to it before you dereference it, e.g. with
mFsqApp = new FoursquareApp();
... or using a value passed in elsewhere (e.g. to the constructor). It's hard to tell which of those is appropriate in this case, but something has to assign a non-null value to it. You say similar code worked earlier in an activity - so look back at that code and see where the value was coming from there.
(Then improve your code to avoid public variables, avoid static variables where possible, avoid catching Exception, avoid just continuing in the face of an exception unless you're really handled it etc.)
I'm probably doing something wrong, but this is what happens:
I register a listener, wait for it to be called and when it executes and calls "Vector.clear()" it locks. The problem happens in the "pipeMsgEvent" method, here it is the, not so friendly-looking, code (if you want, go directly to "this is important" lines):
public class JxtaCustomer implements PipeMsgListener {
public static final int ANSWER_OK = 0;
public static final int ANSWER_TIMEOUT =-1;
public static final int ANSWER_NOT_ASKED =-2;
public static final int ANSWER_WORKING =-3;
public static final int REQ_SENT = 0;
public static final int REQ_INV_PIPE_ID =-1;
public static final int REQ_INV_PIPE_IO =-2;
public static final int REQ_INV_GROUP_ID =-3;
protected int answer;
protected JxtaGenericAdvertisement serviceAdv = null;
protected JxtaNode ThePeer = null;
JxtaBiDiPipe myBiDiPipe = null;
protected Vector<Entry> output = null;
public JxtaCustomer(JxtaGenericAdvertisement adv, JxtaNode peer)
{
ThePeer = peer;
serviceAdv = new JxtaGenericAdvertisement((Element)adv.getDocument(new MimeMediaType("text/xml")));
answer = ANSWER_NOT_ASKED;
Vector<Entry> output = new Vector<Entry>();
}
public void pipeMsgEvent(PipeMsgEvent event)
{
System.out.println("It Works! Uhuuu");
// We received a message
Message message = event.getMessage();
System.out.println("Lets GO! Uhuuu");
Message.ElementIterator elIt = message.getMessageElementsOfNamespace( serviceAdv.getName() );
System.out.println("A little bit more");
answer = ANSWER_WORKING;
System.out.println("enter");
// This is important: Here I get stuck, "clear"
// never appears on the screen
output.clear();
System.out.println("clear");
while (elIt.hasNext()) {
MessageElement mElem = elIt.next();
System.out.println(mElem.getElementName() + " " + mElem.toString());
output.add( new Entry( mElem.getElementName(), mElem.toString() ) );
}
System.out.println("leave");
answer = ANSWER_OK;
}
public int sendRequest(Vector<Entry> params)
{
try {
// Creating Pipe Advertisement
String pipeAdvType = PipeAdvertisement.getAdvertisementType();
PipeAdvertisement pipeAd = (PipeAdvertisement)AdvertisementFactory.newAdvertisement(pipeAdvType);
URI pipeURI = new URI(serviceAdv.getPipeID());
pipeAd.setPipeID( IDFactory.fromURI(pipeURI) );
pipeAd.setType(PipeService.UnicastType);
pipeAd.setName(serviceAdv.getName() + " Service Pipe");
pipeAd.setDescription("Created by " + serviceAdv.getName());
// Creating Group
JxtaGroup jxgp = ThePeer.getGroupFromID( serviceAdv.getGroupID() );
if (null == jxgp)
return REQ_INV_GROUP_ID;
PeerGroup group = jxgp.getPeerGroup();
if (null == group)
return REQ_INV_GROUP_ID;
// This is important: In the JxtaBiDiPipe call I register
// the callback, while I have access to the code, I think
// the problem is in my code
myBiDiPipe = new JxtaBiDiPipe( group, pipeAd, 30000, this);
if (myBiDiPipe.isBound()) {
Thread.sleep(500);
Message myMessage = new Message();
if (0 == params.size())
params.add( new Entry("dummy", "null") );
for (int i=0; i<params.size(); i++) {
String Key = params.get(i).getKey();
String Value = params.get(i).getValue();
StringMessageElement strMsgElem = new StringMessageElement( Key, Value, null);
myMessage.addMessageElement( serviceAdv.getName(), strMsgElem);
}
myBiDiPipe.sendMessage(myMessage);
answer = ANSWER_TIMEOUT;
return REQ_SENT;
}
} catch (URISyntaxException e){
e.printStackTrace();
return REQ_INV_PIPE_ID;
} catch (IOException e) {
return REQ_INV_PIPE_IO;
} catch (Exception e) {
e.printStackTrace();
}
return REQ_INV_PIPE_IO;
}
public Vector<Entry> getResponse()
{
Vector<Entry> results = new Vector<Entry>();
if (ANSWER_OK != answer)
return results;
// This is important: I always call "getState()" and check its value
// before calling this method, so you can say it's guaranteed to be
// called after answer = ANSWER_OK, which never happens because of the
// lock
for (int i=0; i<output.size(); i++)
results.add( output.get(i) );
return results;
}
public int getState()
{
int count = 10;
return answer;
}
}
I always create JxtaCustomer like this:
JxtaCustomer customer = new JxtaCustomer(adv, ThePeer);
Vector<Entry> params = new Vector<Entry>();
params.add( new Entry("key1", "value1") );
params.add( new Entry("key2", "value2") );
customer.sendRequest(params);
while(JxtaCustomer.ANSWER_OK != customer.getState()) {
// I was actually using synchronized locks and timed waits
// but since I'm stuck there I'm using this nonsense instead
}
Vector<Entry> response = customer.getResponse();
Here is where in the code I call "sleep", "wait" or I create a "synchronized" (this last one is never)
$ grep synchronized $(find . -name "*.java")
$ grep sleep $(find . -name "*.java")
./Src/net/ubi/jxta/JxtaCustomer.java: Thread.sleep(500);
$ grep wait $(find . -name "*.java")
./App/ExampleServices/SimpleSigner.java: boolean waiting = false;
./App/ExampleServices/SimpleSigner.java: waiting = true;
./App/ExampleServices/SimpleSigner.java: return (waiting && JxtaCustomer.ANSWER_OK == customer.getState());
./App/ExampleServices/SimpleSigner.java: if (!waiting)
./App/ExampleServices/SimpleSigner.java: waiting = false;
./App/ExampleServices/SimpleSigner.java: return "Error: Response not ready, wait more time\n";
Your constructor sets a local variable called output,and not the member variable, you have
Vector<Entry> output = new Vector<Entry>();
when it should be
output = new Vector<Entry>();
So, later on when you call output.clear() you're getting an Null Pointer Exception thrown, which is why the following lines of code don't get executed.
compiler warnings like "unused local variables" can help spot these sorts of mistakes.