I have been working with the YouTube API v3 with Java and have encountered a problem.
When trying to set a variable in an array I am getting a NullPointerException. It seems completely random and impossible. I am getting this on this line:
full[0] = snippet.getDisplayMessage().toLowerCase();
in this method:
private static void listChatMessages(
final String liveChatId,
final String nextPageToken,
long delayMs) {
System.out.println(
String.format("Getting chat messages in %1$.3f seconds...", delayMs * 0.001));
Timer pollTimer = new Timer();
pollTimer.schedule(
new TimerTask() {
#Override
public void run() {
try {
// Get chat messages from YouTube
LiveChatMessageListResponse response = youtube
.liveChatMessages()
.list(liveChatId, "snippet, authorDetails")
.setPageToken(nextPageToken)
.setFields(LIVE_CHAT_FIELDS)
.execute();
// Display messages and super chat details
List<LiveChatMessage> messages = response.getItems();
for (int i = 0; i < messages.size(); i++) {
LiveChatMessage message = messages.get(i);
LiveChatMessageSnippet snippet = message.getSnippet();
final String[] full = new String[2];
full[0] = snippet.getDisplayMessage().toLowerCase();
full[1] = message.getId();
ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
es.submit(new Runnable() {
public void run() {
PressKey.main(full);
}
});
}
// Request the next page of messages
listChatMessages(
liveChatId,
response.getNextPageToken(),
response.getPollingIntervalMillis());
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
}, delayMs);
}
}
I am not entirely sure how the API is implemented, but this NPE happens because the value of
snippet.getDisplayMessage()
Is null, and calling .toLowerCase() on null results in the NPE.
Like I said, I do not know for sure how the API and the container classes are implemented, but it may seem like getDisplayMessage() is not always guaranteed to return any content.
You could fix your NPE by checking for null values and supplying a default value instead:
full[0] = snippet.getDisplayMessage() == null ? "" : snippet.getDisplayMessage().toLowerCase();
Here we assign an empty string to full[0] if getDisplayMessage() is null.
Related
I'm trying to build a system in which I can connect some devices to a server over the internet.
I want to stream some data over CoAP (10-30FPS), frame size = 3KB.
Firstly, I used Aiocoap, it sends up to 100FPS but uses too much CPU,
requests are NON, got low lose rate in Aiocoap,
while Eclipse/Californium could not send more than 3FPS,
when i use higher FPS, either I receive only the first block of each message or receiving nothing, also not ordered most of the times.
I was wondering if this is the real performance of Californium or am I using it in a wrong way?
I will share some code:
server.java
static class CoapObserverServer extends CoapResource {
int i = -1;
public CoapObserverServer() {
super("alarm");
setObservable(true); // enable observing
setObserveType(Type.NON); // configure the notification type to CONs
getAttributes().setObservable(); // mark observable in the Link-Format
System.out.println(this);
// schedule a periodic update task, otherwise let events call changed()
//new Timer().schedule(new UpdateTask(), 0, 1000/2);
}
private class UpdateTask extends TimerTask {
#Override
public void run() {
changed(); // notify all observers
}
}
#Override
public void handleGET(CoapExchange exchange) {
// the Max-Age value should match the update interval
exchange.setMaxAge(1);
//++i;
int leng = 2000;
String s = "" + i + "-" + fillString('X', leng - 1 - Integer.toString(i).len>
exchange.respond(s);
}
public static String fillString(char fillChar, int count){
// creates a string of 'x' repeating characters
char[] chars = new char[count];
while (count>0) chars[--count] = fillChar;
return new String(chars);
}
#Override
public void handleDELETE(CoapExchange exchange) {
delete(); // will also call clearAndNotifyObserveRelations(ResponseCode.NOT_>
exchange.respond(ResponseCode.DELETED);
}
#Override
public void handlePUT(CoapExchange exchange) {
exchange.accept();
int format = exchange.getRequestOptions().getContentFormat();
if (format == MediaTypeRegistry.TEXT_PLAIN) {
// ...
String plain = exchange.getRequestText();
try{
i = Integer.valueOf(plain);
} catch(NumberFormatException ex){
System.out.println("error converting string"+ plain);
}
exchange.respond(ResponseCode.CHANGED);
changed(); // notify all observers
}
}
Observer.java
private static final File CONFIG_FILE = new File("Californium3.properties");
private static final String CONFIG_HEADER = "Californium CoAP Properties file for client";
private static final int DEFAULT_MAX_RESOURCE_SIZE = 2 * 1024 * 1024; // 2 MB
private static final int DEFAULT_BLOCK_SIZE = 512;
static {
CoapConfig.register();
UdpConfig.register();
}
private static DefinitionsProvider DEFAULTS = new DefinitionsProvider() {
#Override
public void applyDefinitions(Configuration config) {
config.set(CoapConfig.MAX_RESOURCE_BODY_SIZE, DEFAULT_MAX_RESOURCE_SIZE);
config.set(CoapConfig.MAX_MESSAGE_SIZE, DEFAULT_BLOCK_SIZE);
config.set(CoapConfig.PREFERRED_BLOCK_SIZE, DEFAULT_BLOCK_SIZE);
}
};
private static class AsynchListener implements CoapHandler {
#Override
public void onLoad(CoapResponse response) {
System.out.println( response.getResponseText() );
}
#Override
public void onError() {
System.err.println("Error");
}
}
/*
* Application entry point.
*/
public static void main(String args[]) {
Configuration config = Configuration.createWithFile(CONFIG_FILE, CONFIG_HEADER, DEFAULTS);
Configuration.setStandard(config);
URI uri = null; // URI parameter of the request
if (args.length > 0) {
// input URI from command line arguments
try {
uri = new URI(args[0]);
} catch (URISyntaxException e) {
System.err.println("Invalid URI: " + e.getMessage());
System.exit(-1);
}
CoapClient client = new CoapClient(uri);
client.useNONs();
// observe
AsynchListener asynchListener = new AsynchListener();
CoapObserveRelation observation = client.observe(asynchListener);
// User presses ENTER to exit
System.out.println("Press ENTER to exit...");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try { br.readLine(); } catch (IOException e) { }
System.out.println("Exiting...");
observation.proactiveCancel();
}
So i'm controlling the FPS by sending PUT requests with a server that has a counter 0-50.
Not sure, what your doing.
That seems to be wired and not related to RFC7252 nor RFC7641.
CoAP is designed for REST, I don't see any benefit in using it for video streaming.
Using Eclipse/Californium on a Intel n6005 with 16GB RAM, the CoAP/DTLS server runs on about 60000 requests/second. The benchmark uses 2000 clients in parallel.
See also Eclipse/Californium - Benchmarks j5005
Using only one client with CON requests, the performance is mainly limited by the RTT. 30 requests/second should work, if that RTT is accordingly small.
Using NON requests doesn't really help. CoAP RFC7252 defines two layers, a messaging layer and an application layer. NON affects only the messaging layer, but a NON request will wait for it's response, if NSTART-1 should be used.
If your RTT is the issue, you may try to escape that either using requests with "No Server Response" (RFC7967) or multiple NON responses (RFC7641). The first is not intended for fast requests, the second is more a work-around of the initial statement, that CoAP is REST not video-streaming.
So, what is your RTT?
I have 10 health check URLs which are simply get service
I am hitting them in a loop like below
for(int i=0;i<10;i++){
Response response = given().when().relaxedHttpsValidation().get(url[i]);
list.add(response);
}
return list;
Now the problem is it hits API in series and waiting for a response for all, I just want to hit all API in parallel but combine the result, I tried using threads but unable to get an idea on how to combine the response in case of multi-threading
If I am reading your question right I believe you want to make parallel calls and combine the results, and in that case I would suggest you to make use of TestNG. I had a similar requirement in the past and this link helped me out
Here's a sample code
public class Parallel {
#DataProvider(parallel = true)
public Object[] getURL() {
return new Object[] { "https://reqres.in/api/users/1", "https://reqres.in/api/users/2",
"https://reqres.in/api/users/3", "https://reqres.in/api/users/4", "https://reqres.in/api/users/5",
"https://reqres.in/api/users/6" };
}
ArrayList<String> original = new ArrayList<String>();
#Test(dataProvider = "getURL")
public void stack(String url) {
Response response = given().when().get(url);
JsonPath js = response.jsonPath();
String email = js.getString("data.email");
original.add(js.getString("data.email"));
}
#AfterTest
public void simple() {
System.out.println("List : " + original);
}
}
Just remove (parallel = true) to see how it works sequentially. I have extracted the email field from the response using JSONPath and added to the list
Don't forget to update the POM
Thank you for your quick response i just want to share now how i achieved it
List responseList = new ArrayList();
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
exec.submit(new Runnable() {
public void run() {
String response = executeServiceCall(urlArray[i]);
responseList.add(response);
}
});
} exec.shutdown();
try {
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
LOGGER.error(e.toString());
}
LOGGER.info("response list is " + responseList)
GitHub Repo app building for learning purposes I've become stuck in this world of NullPointerException.
So it says on line 119 the ArrayList is null it's a simple Callback via Retrofit
where I try to get the data and then set they data further on. I'm unsure of where exactly in the process it fails as it just points to the initialization of the array on line 119 but I'm iterating over that array and then adding each item to a collection.
Someone with more knowhow would be able to spot something that I can't.
Any advice welcome.
Call<GitHubRepo> call = gitHubClient.getRepos(searchTerm, pageNumber, resultsPerPage);
call.enqueue(new Callback<GitHubRepo>() {
#Override
public void onResponse(Call<GitHubRepo> call, Response<GitHubRepo> response) {
ArrayList<Item> itemsList = response.body().getItems();
for(int i = 0; i < itemsList.size(); i++) {
ModelCachedGitHubProject currentProject = new ModelCachedGitHubProject();
Item responseItem = itemsList.get(i);
currentProject.setOwnerName(responseItem.getOwner().getLogin());
currentProject.setRepoName(responseItem.getName());
currentProject.setRepoSize(responseItem.getSize());
currentProject.setHasWiki(responseItem.isHas_wiki());
currentProject.setCreatedAt(responseItem.getCreated_at());
currentProject.setPushedAt(responseItem.getPushed_at());
currentProject.setUpdatedAt(responseItem.getUpdated_at());
currentProject.setHtmlUrl(responseItem.getHtml_url());
currentProject.setAvatarUrl(responseItem.getOwner().getAvatar_url());
currentProject.setLanguage(responseItem.getLanguage());
currentProject.setForksCount(responseItem.getForks_count());
currentProject.setScore(responseItem.getScore());
currentProject.setDescription(responseItem.getDescription());
gitHubProjectsList.add(currentProject);
}
Any other classes that are needed just ask. Thanks.
StackTrace :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.benmohammad.repoapp, PID: 2325
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.benmohammad.repoapp.data.webservice.apiresponse.GitHubRepo.getItems()' on a null object reference
at com.benmohammad.repoapp.data.DataRepository$1.onResponse(DataRepository.java:119)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda
GitHub Repo Repo
Thanks
public void updateFromWebservice(final String searchTerm, final int pageNumber, int resultsPerPage) {
webServiceMessageCallStatus.setValue(WebServiceMessage.UPDATING_STATUS);
final List<ModelCachedGitHubProject> gitHubProjectsList = new ArrayList<>();
if(retrofit == null || gitHubClient == null) {
retrofit = new Retrofit.Builder().baseUrl(GitHubClientService.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
gitHubClient = retrofit.create(GitHubClientService.class);
}
Call<GitHubRepo> call = gitHubClient.getRepos(searchTerm, pageNumber, resultsPerPage);
call.enqueue(new Callback<GitHubRepo>() {
#Override
public void onResponse(Call<GitHubRepo> call, Response<GitHubRepo> response) {
ArrayList<Item> itemsList = response.body().getItems();
for(int i = 0; i < itemsList.size(); i++) {
ModelCachedGitHubProject currentProject = new ModelCachedGitHubProject();
Item responseItem = itemsList.get(i);
currentProject.setOwnerName(responseItem.getOwner().getLogin());
currentProject.setRepoName(responseItem.getName());
currentProject.setRepoSize(responseItem.getSize());
currentProject.setHasWiki(responseItem.isHas_wiki());
currentProject.setCreatedAt(responseItem.getCreated_at());
currentProject.setPushedAt(responseItem.getPushed_at());
currentProject.setUpdatedAt(responseItem.getUpdated_at());
currentProject.setHtmlUrl(responseItem.getHtml_url());
currentProject.setAvatarUrl(responseItem.getOwner().getAvatar_url());
currentProject.setLanguage(responseItem.getLanguage());
currentProject.setForksCount(responseItem.getForks_count());
currentProject.setScore(responseItem.getScore());
currentProject.setDescription(responseItem.getDescription());
gitHubProjectsList.add(currentProject);
}
if(!gitHubProjectsList.isEmpty()) {
boolean clearPreviousCache;
if(pageNumber == 1) {
clearPreviousCache = true;
saveLastSearchTerm(searchTerm);
} else clearPreviousCache = false;
cacheProjectsList(gitHubProjectsList, clearPreviousCache);
setLastRefreshDate(new Date());
webServiceMessageCallStatus.postValue(WebServiceMessage.ON_RESPONSE_SUCCESS);
} else {
if(pageNumber == 1)
webServiceMessageCallStatus.postValue(WebServiceMessage.ON_RESPONSE_NOTHING_FOUND);
else {
webServiceMessageCallStatus.postValue(WebServiceMessage.ON_RESPONSE_NO_MORE_RESULTS);
}
}
}
#Override
public void onFailure(Call<GitHubRepo> call, Throwable t) {
webServiceMessageCallStatus.postValue(WebServiceMessage.ON_FAILURE);
}
});
}
Response is null, assuming you are talking about ArrayList itemsList line.. We can't see line numbers. If you look at the stack trace, it says .getItems()' on a null object reference. That means response.getBody() is null. So you need to check where that response is being initialized (being sent) and make sure there isn't a problem in that class/service.
I'm using socket.io for my chat app. I have an ArrayList which contains last message, username, time. Whenever a new message arrives in JSON format then it should check if JSON contained username is present in ArrayList or not. If present, then updates the ArrayList otherwise add in ArrayList.
Here is my code:-
private Emitter.Listener handle1 = new Emitter.Listener() {
#Override
public void call(final Object... args) {
ChatLists.this.runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject)args[0];
try {
String sendername = data.getString("sender");
String lastMessage = data.getString("message");
String profileImage = data.getString("Profile");
String token = data.getString("fb_token");
chat_list chat_list = new chat_list(sendername,
profileImage, lastMessage, "0", "", "dummy", token);
if (chat_lists.size()==0){
chat_lists.add(chat_list);
}else {
for (int i=0;i<chat_lists.size();i++){
if (chat_lists.get(i).getContactname().equals(sendername)){
chat_lists.set(i,chat_list);
}else {
chat_lists.add(chat_list)
}
}
}
contactlistAdapter = new ContactlistAdapter(chat_lists);
recyclerView.setAdapter(contactlistAdapter);
contactlistAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
};
Well, you can use contains() & set() methods of ArrayList in a logical way to solve your problem like below:-
if(chat_lists.contains(username))
chat_lists.set(indexOf(username), new_username);
else chat_lists.add(new_username);
Try it:
if(chat_lists.contains(chat_list)){
chat_lists.remove(chat_list);
chat_lists.add(chat_list);
} else {
chat_lists.add(chat_list);
}
Read about architecture patterns, for example, MVP.
You need to store your messages somethere (in Model) and update view relative to data.
Also read about RecyclerView, cause of ListView is a little bit deprecated
if (chat_lists.get(i).getContactname().equals(sendername)){
above statement has problem them. It's not getting under your if condition and following the chat_lists.add(chat_list) statement.
Instead equals use ignoreCasequals. If still wont it solve your problem please use debug mode or logs check chat_lists.get(i).getContactname()
and sendername same or not.
I'm trying to get PhotoUrl in this method.
private String getUserPhotoUrl(String vk_id){
final String[] url = new String[1];
VKRequest request = VKApi.users().get(VKParameters.from(VKApiConst.USER_ID, vk_id,
VKApiConst.FIELDS, "photo_100"));
request.executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onComplete(final VKResponse response) {
super.onComplete(response);
new Thread(){
#Override
public void run() {
VKList<VKApiUser> User = (VKList<VKApiUser>) response.parsedModel;
url[0] = User.get(0).photo_100;
Log.i("PhotoUrl", url[0]); //working perfect
}}.start();
}});
return url[0];
}
In the Log.i("PhotoUrl", url[0]); it gives not null. I mean normal url. But when I try to return it in return url[0]; part, it gives me null. Any ideas?
Because of concurrency. Your method immediately returns without waiting for any other thread.
The return statement is outside the listener, and thefore returns befofre listener end processing.
So it returns a null