why run and start call simultaneously in java - java

I am learning a tutorial about how to consume json web service.
But I have two doubts can you please help me in understanding.
I am learning from this link
http://codeoncloud.blogspot.in/2013/05/blackberry-java-json-tutorial.html
Here is one class extend by thread
public class ConnectJson extends Thread {
private String url;
public String response;
private String myinterface = ";interface=wifi";
public void run() {
HttpConnection conn = null;
InputStream in = null;
int code;
try {
conn = (HttpConnection) Connector.open(this.url + this.myinterface, Connector.READ);
conn.setRequestMethod(HttpConnection.GET);
code = conn.getResponseCode();
if (code == HttpConnection.HTTP_OK) {
in = conn.openInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[in.available()];
int len = 0;
while (-1 != (len = in.read(buffer))) {
out.write(buffer);
}
out.flush();
this.response = new String(out.toByteArray());
if (out != null){
out.close();
}
if (in != null){
in.close();
}
if (conn != null){
conn.close();
}
}
} catch (Exception e) {
Dialog.inform(e.toString());
}
}
public String jsonResult(String url){
this.url = url;
this.start();
this.run();
return response;
}
}
It is making one object of that class and call method of that class .In that method it call start as well as run method why ?
this.start();
this.run();?

In that method it call start as well as run method why ?
You'd have to ask the author of the code; looking at that class's code, it looks incorrect. It's also fairly unusual.
In the normal course of things, you don't call run directly; you start the thread (with start) and the JVM is then responsible for creating a new thread and calling run on it.
You can call run yourself if you really want that code to run right away on the current thread, but it's unusual and that class doesn't immediately look like it's designed to do that correctly. What that code actually does is start a new thread (which means run will eventually get called on that new thread), but then as you observed it also calls run directly. So run will run twice, and may well run twice simultaneously. Since the code in run uses instances variables that will be used by both threads but doesn't do anything to coordinate access to those instance variables...well, again, it looks incorrect.
I don't think I'd keep following that tutorial. You may find the Concurrency trail in the Java tutorials from Oracle might be useful. (Threads are part of it.)

Related

Why Selenium's DriverService prints to the error stream? and how to avoid it? - Java

I’m using Selenium with ChromeDriverService.
In its base class, DriverService, it starts the service and prints output messages to System.err stream.
private CommandLine process = null;
public void start() throws IOException {
lock.lock();
try {
if (process != null) {
return;
}
process = new CommandLine(this.executable, args.toArray(new String[] {}));
process.setEnvironmentVariables(environment);
process.copyOutputTo(System.err);
process.executeAsync();
waitUntilAvailable();
} finally {
lock.unlock();
}
}
My first question is why to the error stream? It just prints some info messages about the initialization of chrome driver.
In my application, everything that goes to System.err shown in the app’s log with SEVERE log level.
My second question is how can I avoid it and show it as INFO log level?
It is impossible to extend ChromeDriverService and override the start method, because DriverService contains some private data members that I need and can’t access to.
Thanks.
P.S. I’m using Selenium 2.5.2 but it’s the same concept in the newer versions
Selenium 3.14.0 From DriverService, you are correct the default is System.err. It does look like you can change this default value as shown below and in the newer version the start() method has changed to use getOutputStream(). This will now allow you to change the default value.
private OutputStream outputStream = System.err; // default
// You should call this method and set the output to your desired location
public void sendOutputTo(OutputStream outputStream) {
this.outputStream = Preconditions.checkNotNull(outputStream);
}
public void start() throws IOException {
lock.lock();
try {
if (process != null) {
return;
}
process = new CommandLine(this.executable, args.toArray(new String[] {}));
process.setEnvironmentVariables(environment);
process.copyOutputTo(getOutputStream()); // This has changed...
process.executeAsync();
waitUntilAvailable();
} finally {
lock.unlock();
}
}

Connecting arduino to an android app which uses libgdx (using Bluetooth)

so i'm trying to do something a little unusual, it's just for fun. I have a game i created using libgdx, it consists of a ship that can shoot. What i want to do is to use some external push buttons to move it. The push buttons send signals to arduino, which in turn sends them to an HC-05 bluetooth module. however i'm very doubtful about the android side of things. What i did basically was the following:
Because i'm working on libgdx i created an interface called BluetoothDude, with three methods setBluetooth() (which will set the bluetooth for the particular platform),String whatIsTheMessage() (which will tell you what's been sent to the phone), and boolean isActive(), to know if the bluetooth is active of course.
The MainGame will receive a BluetoothDude so that particular classes like Ship have access to the Message and are able to react to it.
Then i did the particular implementation of Bluetooth for android, in the setBluetooth() i followed this guide very closely: https://developer.android.com/guide/topics/connectivity/bluetooth.html
i'm sure it is connecting properly, because when it creates the socket it can print "connection success with HC-05" (it will only print that if the method which creates the sockets, which i called BTConnect() returns true).
The problem seems to be in reading the data, the code i'm using is
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private Handler handler;
public ConnectedThread(BluetoothSocket socket,Handler mHandler) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
handler = mHandler;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
handler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
i made an object of this class in setBluetooth like this
if (device != null) {
if (BTconnect()) {
isActive = true;
connectedThread = new ConnectedThread(socket,handler);
System.out.println("connection success with" + device.getName() + " message: " + message );
}
i have a lot of doubts
first what is the target here, the mHandler was created in BluetoothDude, so is that the target?, second i'm quite sure the thread isn't even running because if i put a line like System.out.println("run") inside run() it doesn't show me the line like a trillion times in the logcat when the app is executed. What is wrong with it, i hope you can help me, i'm not very experienced at all of this, and it's driving me crazy.
I cannot see if this is the case from your code but if you are calling platform specific methods, that should be done in the platform specific project subproject.
For more information on how to do that you can check out this page :
https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code
So if your LibGDX game has a function say, "setBluetooth" each platform will have its own implementation of said method. That will differ when you compile for Android or iOS.
If you try to call platform specific code in your core game probably won't work.
Hope it helps, maybe you have already done that in which case you can ignore my comment.

How can I recreate a chained OutputStream with only filename modified

I have got an OutputStream which can be initialized as a chain of OutputStreams. There could be any level of chaining .Only thing guaranteed is that at the end of the chain is a FileOutputStream.
I need to recreate this chained outputStream with a modified Filename in FileOutputStream. This would have been possible if out variable (which stores the underlying chained outputStream) was accessible ; as shown below.
public OutputStream recreateChainedOutputStream(OutputStream os) throws IOException {
if(os instanceof FileOutputStream) {
return new FileOutputStream("somemodified.filename");
} else if (os instanceof FilterOutputStream) {
return recreateChainedOutputStream(os.out);
}
}
Is there any other way of achieving the same?
You can use reflection to access the os.out field of the FilterOutputStream, this has however some drawbacks:
If the other OutputStream is also a kind of RolloverOutputStream, you can have a hard time reconstructing it,
If the other OutputStream has custom settings, like GZip compression parameter, you cannot reliable read this
If there is a
A quick and dirty implementation of recreateChainedOutputStream( might be:
private final static Field out;
{
try {
out = FilterInputStream.class.getField("out");
out.setAccessible(true);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public OutputStream recreateChainedOutputStream(OutputStream out) throws IOException {
if (out instanceof FilterOutputStream) {
Class<?> c = ou.getClass();
COnstructor<?> con = c.getConstructor(OutputStream.class);
return con.invoke(this.out.get(out));
} else {
// Other output streams...
}
}
While this may be ok in your current application, this is a big no-no in the production world because the large amount of different kind of OutputStreams your application may recieve.
A better way to solve would be a kind of Function<String, OutputStream> that works as a factory to create OutputStreams for the named file. This way the external api keeps its control over the OutputStreams while your api can adress multiple file names. An example of this would be:
public class MyApi {
private final Function<String, OutputStream> fileProvider;
private OutputStream current;
public MyApi (Function<String, OutputStream> fileProvider, String defaultFile) {
this.fileProvider = fileProvider;
selectNewOutputFile(defaultFile);
}
public void selectNewOutputFile(String name) {
OutputStream current = this.current;
this.current = fileProvider.apply(name);
if(current != null) current.close();
}
}
This can then be used in other applications as:
MyApi api = new MyApi(name->new FileOutputStream(name));
For simple FileOutputStreams, or be used as:
MyApi api = new MyApi(name->
new GZIPOutputStream(
new CipherOutputStream(
new CheckedOutputStream(
new FileOutputStream(name),
new CRC32()),
chipper),
1024,
true)
);
For a file stream that stored checksummed using new CRC32(), chipped using chipper, gzip according to a 1024 buffer with sync write mode.

Try to use Agent in Webapplication for bytecode Manupulation

I'm not that good in Java but I have my webApplication running on a Wildfly.
I have 3 threads who just call a function that insert logs in in and the function saves the logs to a Database and after that every thread sends a time how long did it takes to do this.
They send the data to another programm I wrote what has 3 threads to call one of the 3 server threads.
So now I try to do some ByteCode Manipulation every thread on the server saves the datetime call the log function waits 1 second and returns then the time they needed.
1 Thread write something in an logfile before or after they waitet 1 second.
But this part where they wait a second and call the log function I want that to inject to every 3 threads with Bytecode manipulation.
public class MyTransformer implements ClassFileTransformer {
#Override
public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException {
return transformClass(redefiningClass, bytes);
}
private byte[] transformClass(Class classToTransform, byte[] b) {
ClassPool pool = ClassPool.getDefault();
CtClass cl = null;
try {
cl = pool.get("de.soptim.ws.MyApplication");
} catch (javassist.NotFoundException e) {
e.printStackTrace();
}
try {
assert cl != null;
CtMethod[] methods = cl.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isEmpty() == false) {
changeMethod(methods[i]);
}
}
b = cl.toBytecode();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cl != null) {
cl.detach();
}
}
return b;
}
private void changeMethod(CtMethod method) throws NotFoundException, CannotCompileException {
if (method.hasAnnotation(Loggable.class)) {
method.insertBefore("threadLogger.info(\"ADDED THIS FROM BYTECODE !!!\");");
method.insertAfter("threadLogger.info(\"ADDED THIS FROM BYTECODE !!!\");");
}
}}
Thats my transformer class it should increase the Code my Methods need it checks what Method has an #Loggable annotation an then adds the code into it("at the moment it's just some log statments for checking if it works")
My biggest problem is now that I don't know how to call my agent ... I googled hwo to call an agent at runtime with agentmain() but I think I dind't really understood how it works.
Agent Class
public class LogAgent {
public static void agentmain(String agentArgs, Instrumentation inst) {
System.out.println("Starting the agent");
inst.addTransformer(new MyTransformer());
}}
Hope you understand My problem :) I and if you answere pleas try to stay noob friendly :D.
you don't call your agent explicitly, you should specify additional argument to your JVM :
java -javaagent:jarpath[=options]
where jarpath is a path to jar containing your agent. JVM will invoke premain method before main method of java program.
And transform method will be called before classloading by JVM (you don't call it explicitly).
Last remark : you should implement premain method, not agentmain.
agentmain is used during attaching to running vm, while premain is used when you start JVM with -javaagent method.
And make sure that your jar have valid manifest, as described : https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html
I haven't using javaassit so I cannot say that your code is valid, but instrumenting webapp server like Wildfly is much harder than normal java app (mostly due to classloaders visibility and hierarchy).
See also :
http://www.tomsquest.com/blog/2014/01/intro-java-agent-and-bytecode-manipulation/
Tutorials about javaagents

nearest equivalent of a webpage reload in java

I am taking some data from a database via a servlet and a db handler java class and hosting it at a url. Since the database is changing I'm taking care only to host the changes rather than the entire db data.
I'm getting the required functionality by a browser i.e after every (manual) reload, I'm getting the data as required by me,
1. at the first page load, entire data gets displayed.
2. at subsequent reloads, I get either null data if there is no change in the database, or the appended rows if the database extends. (the database can only extend).
But then in a java program, I'm not getting the same functionality. The java program using HttpUrlConnection.
This is the code for the java client for servlet...
public class HTTPClient implements Runnable {
private CallbackInterface callbackinterface;
private URL url;
private HttpURLConnection http;
private InputStream response;
private String previousMessage = "";
public HTTPClient() {
try {
url = new URL("http://localhost:8080/RESTful-Server/index.jsp");
http = (HttpURLConnection) url.openConnection();
http.connect();
} catch (IOException e) {
}
}
#Override
public void run() {
while (true) {
try {
String currentmessage = "";
response = http.getInputStream();
if (http.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader buffread = new BufferedReader(new InputStreamReader(response));
String line;
for (; (line = buffread.readLine()) != null;) {
currentmessage += line;
}
if ((!currentmessage.equals(previousMessage)
|| !previousMessage.equals(""))
&& !currentmessage.equals("")) {
//this.callbackinterface.event(currentmessage);\
System.out.println(currentmessage + "\t" + previousMessage);
}
previousMessage = currentmessage;
Thread.sleep(2500);
} else {
throw new IOException();
}
} catch (IOException | InterruptedException e) {
System.err.println("Exception" + e);
}
}
}
The shown class is a thread which read the connections every 2.5 s. If it gets something significant in the getline(), it will issue a callback to a worker method, which takes care of remaining things.
I am thinking the issues is because of the class variable conn, and that reload as in the browser is not getting replicated..
Any idea how to do this?
You're basically connecting (requesting) only once and trying to read the response multiple times, while it can be read only once. You basically need to create a new connection (request) everytime. You need to move the creation of the connection by url.openConnection() to inside the loop. The line http.connect() is by the way superfluous. You can safely omit it. The http.getInputStream() will already implicitly do it.
See also:
Using java.net.URLConnection to fire and handle HTTP requests

Categories

Resources