I want to run one HTML page with JavaScript and want to access its output in Java. Is there any way to access JavaScript console output of browser in Java code?
First, I tried executing JavaScript using Java (htmlunit) but it gave an error due to jQuery in the JS.
The JS function which I need to execute uses associated HTML elements, and that's why I preferred to save the page, add my JS to that page, and run it locally. I can then see the output on the JavaScript console, and now I want to get that output in Java code for further processing.
I want to run one HTML page with JavaScript and want to access its output in Java. Is there any way to access JavaScript console output of browser in Java code?
First, I tried executing JavaScript using Java (htmlunit) but it gave an error due to jQuery in the JS.
The JS function which I need to execute uses associated HTML elements, and that's why I preferred to save the page, add my JS to that page, and run it locally. I can then see the output on the JavaScript console, and now I want to get that output in Java code for further processing.
Share Improve this question edited Dec 15, 2014 at 3:48 tckmn 59.4k27 gold badges118 silver badges156 bronze badges asked Sep 8, 2012 at 20:09 PradeepPradeep 6,6139 gold badges39 silver badges61 bronze badges 5-
Is the Java executing the Javascript? Or do you want to link to a js file and the java logs all the
console.log
outputs? You'll have to be more specific... – jeremy Commented Sep 8, 2012 at 20:16 - 1 One does not run an HTML page. You might want to look into V8 or another Javascript engine if you want to be able to access its output. – Waleed Khan Commented Sep 8, 2012 at 20:36
- but problem is , i can't run javascript alone as it uses some dynamic html elements from web page , am i be able to execute them(js+html) using these engines ? – Pradeep Commented Sep 8, 2012 at 20:39
- Are you trying to write tests for your JavaScript code? You might want to look at a web browser testing framework like Selenium or Watir. – Daniel Pryden Commented Sep 8, 2012 at 20:47
- No i am not running tests, i just want to take output from ofuscated java script by calling java script method – Pradeep Commented Sep 8, 2012 at 20:50
5 Answers
Reset to default 2Thanks all for quick responses, we solved the problem using Greasemonkey and firefox. Instead of console we are writing output to the file using one servlet. The installed js inside Greasemokey execute js method and output from that is passed over one Servlet(locally running) get request and it writes input to file and we can use that file in java, Inside file write code just added synchronized block in case multiple links opened by Greasemonkey :D
Try Selenium to access the page. It opens a real browser instance and clicks (solves the jquery issues) and should also be able to fetch console.log
.
Maybe this list of JS unit test tools might help you as well: JavaScript unit test tools for TDD
Ofcourse. Read slowly:
One brilliant thought I got is, since you are running java, why not make it a server that will listen on a specific port? You can easily do that.
Once you have got a simple thread listening on a port, in what ever javascript code your are executing, at the end when you want to log some variables to console, send an ajax call to this local server with all the data you want to send to java.
Once you get a request in server, pass the data to other thread and yield.
Even if it looks plex, seems like a pretty feasible solution to me.
I liked Prasanth's suggestion, and it worked well for me. Here's my code.
RCP:
logger = ...
private void startJSConsole() {
jsConsoleJob = new Job("JS Console Server") {
@Override
protected IStatus run(IProgressMonitor monitor) {
Socket connectionSocket = null;
try {
jsSocket = new ServerSocket(6789);
while (!monitor.isCanceled()) {
connectionSocket = jsSocket.accept();
readSocketData(connectionSocket);
}
} catch (IOException e) {
if (!"Socket closed".equals(e.getMessage())) {
logger.logError("Unable to open or read from Javascript console server socket", e);
}
return Status.CANCEL_STATUS;
} finally {
try {
if (jsSocket != null) {
jsSocket.close();
}
if (connectionSocket != null) {
connectionSocket.close();
}
} catch (IOException e) {
//pass
}
}
return Status.OK_STATUS;
}
};
jsConsoleJob.setUser(false);
jsConsoleJob.setSystem(true);
jsConsoleJob.schedule();
}
//I copied this code from here: http://stackoverflow./a/21729100/2036650
private void readSocketData(Socket connectionSocket) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
// read request
String line;
line = in.readLine();
StringBuilder raw = new StringBuilder();
raw.append("" + line);
boolean isPost = line.startsWith("POST");
int contentLength = 0;
while (!(line = in.readLine()).equals("")) {
raw.append('\n' + line);
if (isPost) {
final String contentHeader = "Content-Length: ";
if (line.startsWith(contentHeader)) {
contentLength = Integer.parseInt(line.substring(contentHeader.length()));
}
}
}
StringBuilder body = new StringBuilder();
if (isPost) {
int c = 0;
for (int i = 0; i < contentLength; i++) {
c = in.read();
body.append((char) c);
}
}
raw.append(body.toString());
System.err.println("JS: " + body.toString());
connectionSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Javascript:
<html>
<head>
...
<script>
var global = global || {};
global.consoleLog = function(msg) {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:6789", true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send(msg);
}
</script>
<script src="js/sigplot-minimized.js"></script>
</head>
<body>
...
</body>
</html>
Then from anywhere in the Javascript code:
global.consoleLog(logMessage);
For to plete @MinuitJava answer, you can also add a listener on error events.
window.addEventListener('error', function (e) {
console.log(e.type + " : " + e.message + "\n");
console.log(e);
// var xhttp = new XMLHttpRequest();
// code . . .
});
MDN doc: Window: error event