Title says it all. I am wondering if i can display javascript console.log in eclipse console rather than web browser's dev console?
Just found an article regarding this.
This is How it works(For Window 7).
Install Node.js javascript engine at Node.js
Open your Eclipse, in the menu
Run->External Tools->External Tools Configuration
Create new launch configuration under program category.
Set
Location : C:\WINDOWS\system32\cmd.exe
Working Directory : C:\WINDOWS\system32
Argument : /c "node ${resource_loc}"
Now create new environment variable 'node' refers to node.exe file(wherever you installed)
All done.
Redirect javascript console.logs, in Java console
Here is my solution to get javascript console messages in Java (with SWT browser)
create shell SWT and SWT browser see: Shell + Browser
create custom function SWT see: call Java from JavaScript
Add listener on error events in javascript see: mdn event error
Override console object in javascript and call custom java function (2.)
Here is my example snippet:
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Snippet307d3 {
public static final Shell createShell() {
final var display = new Display();
final var shell = new Shell(display);
shell.setText("Snippet DEBUG");
shell.setLayout(new FillLayout());
shell.setBounds(10, 10, 300, 200);
return shell;
}
public static final Browser createBrowser(Shell shell) {
try {
return new Browser(shell, SWT.NONE);
} catch (final SWTError e) {
System.out.println("Could not instantiate Browser: " + e.getMessage());
shell.getDisplay().dispose();
System.exit(-1);
return null;
}
}
public static final void runShell(Shell shell) {
shell.open();
final var display = shell.getDisplay();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
public static void main(String[] args) {
// -> Create shell
final var shell = createShell();
// -> Create browser
final var browser = createBrowser(shell);
browser.setJavascriptEnabled(true);
// -> set HTML or use setUrl
browser.setText(createHTML());
// browser.setUrl(URL_DOCUMENT_HTML_TEST);
// -> Create custom function
final BrowserFunction function = new CustomFunction(browser, "theJavaFunctionDebugInEclipse");
// -> Register function for cleanup
browser.addProgressListener(ProgressListener.completedAdapter(event -> {
browser.addLocationListener(new LocationAdapter() {
#Override
public void changed(LocationEvent event) {
browser.removeLocationListener(this);
System.out.println("left java function-aware page, so disposed CustomFunction");
function.dispose();
}
});
}));
// -> 6) Start shell
runShell(shell);
}
private static class CustomFunction extends BrowserFunction {
public CustomFunction(Browser browser, String name) {
super(browser, name);
}
#Override
public Object function(Object[] arguments) {
for (final Object v : arguments)
if (v != null)
System.out.println(v.toString());
return new Object();
}
}
private static String createHTML() {
return """
<!DOCTYPE>
<html lang='en'>
<head>
<title>DEBUG SWT</title>
<script>
const console = {
log : function(args) {
try {
theJavaFunctionDebugInEclipse('redirect > ' + args);
} catch (_e) {
return;
}
},
error : function(args) {
this.log(args);
},
exception : function(args) {
this.log(args);
},
debug : function(args) {
this.log(args);
},
trace : function(args) {
this.log(args);
},
info : function(args) {
this.log(args);
}
};
window.addEventListener('error', function(e) {
console.log(e.type + ' : ' + e.message);
console.log(e);
});
</script>
</head>
<body>
<input id=button type='button' value='Push to Invoke Java'
onclick='function1();'>
<p>
<a href='http://www.eclipse.org'>go to eclipse.org</a>
</p>
<script>
// bad char sequence .. send error
eeeee
function function1() {
let result;
try {
// Call bad function java .. send log
result = badFunctionJava(12, false, null, [ 3.6,
[ 'swt', true ] ], 'eclipse');
} catch (e) {
console.log('a error occurred: ' + e.message);
return;
}
}
</script>
</body>
</html>
""";
}
}
Further to #ringord's answer here, these would be the commands for your External Tools Configuration on Linux:
Location : /home/<user>/.nvm/versions/node/<version>/bin/node (or wherever you installed node)
Working Directory : /home/<user>
Arguments : ${container_loc}/${resource_name}
Related
I'm following this tutorial : https://www.baeldung.com/websockets-spring
I tested the app and it works perfectly when running on the embedded-tomcat server. However, when I try to deploy and run the same app on an external tomcat server it breaks, because instead of the URL being
localhost:8080/chat
it becomes
myhostIP:port/spring-boot-web-jsp/chat
So I modified the javascript file adding /spring-boot-web-jsp in front of the existing URLs. When I run the webapp the sockets connect successfully and send data. However now my Spring MVC Controller doesn't work.
My javascript :
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility
= connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS('/spring-boot-web-jsp-1.0/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/spring-boot-web-jsp-1.0/topic/messages', function(messageOutput) {
showMessageOutput(JSON.parse(messageOutput.body));
});
});
}
function disconnect() {
if(stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendMessage() {
var from = document.getElementById('from').value;
var text = document.getElementById('text').value;
stompClient.send("/spring-boot-web-jsp-1.0/app/chat", {},
JSON.stringify({'from':from, 'text':text}));
}
function showMessageOutput(messageOutput) {
var response = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(messageOutput.from + ": "
+ messageOutput.text + " (" + messageOutput.time + ")"));
response.appendChild(p);
}
My Controller :
#MessageMapping("/chat")
#SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
My message broker :
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
}
}
I've tried modifying the Controller to :
#MessageMapping("app/chat")
#SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
#MessageMapping("spring-boot-web-jsp-1.0/app/chat")
#SendTo("spring-boot-web-jsp-1.0/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
and a bunch of other variations but none of them work.
How can I modify the Controller and javascript file to work when testing through external Apache Tomcat as well as embedded (setting a relative URL of some sort)? And how can I get this to work properly on the external Tomcat?
Remove your tomcat/webapps/ROOT directory
Rename your final jar/war/ear file to ROOT.jar/war/ear
Deploy it on tomcat
Tomcat will deploy your app under root directory localhost:8080/chat
Would it be possible in Appium to make a script that calls/references specific tests (e.g test1, test4, test27) to run? So instead of moving files over into the test folder I could just call them using the script is the rough idea I have but I have no idea if it's possible and I haven't been able to find anything similar online.
create group test cases And Create testng.xml file and just invoke testng file and run.
code mport org.testng.Assert;
import org.testng.annotations.Test;
public class GroupTestExample {
String message = ".com";
MessageUtil messageUtil = new MessageUtil(message);
#Test(groups = { "functest", "RunOnlySelectedTestCases" })
public void test1() {
System.out.println("Inside testPrintMessage()");
message = ".com";
Assert.assertEquals(message, messageUtil.printMessage());
}
#Test(groups = { "RunOnlySelectedTestCases" })
public void test4() {
System.out.println("Inside testSalutationMessage()");
message = "tutorialspoint" + ".com";
Assert.assertEquals(message, messageUtil.salutationMessage());
}
#Test(groups = { "RunOnlySelectedTestCases" })
public void test27() {
System.out.println("Inside testExitMessage()");
message = "www." + "tutorialspoint"+".com";
Assert.assertEquals(message, messageUtil.exitMessage());
}
}
?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name = "Suite1">
<test name = "test1">
<groups>
<run>
<include name = "RunOnlySelectedTestCases" />
</run>
</groups>
</test>
</suite>
when I try to run child process and put to it stdin some text it throws error.
here is code of child process:
import java.io.Console;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("started");
Console console = System.console();
while (true) {
String s = console.readLine();
System.out.println("Your sentence:" + s);
}
}
}
code of script which run this process:
var spawn = require('child_process').spawn;
var child = spawn('java', ['HelloWorld', 'HelloWorld.class']);
child.stdin.setEncoding('utf-8');
child.stdout.pipe(process.stdout);
child.stdin.write("tratata\n");
// child.stdin.end();
it throws:
events.js:161
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at exports._errnoException (util.js:1028:11)
at Pipe.onread (net.js:572:26)
notice, when I uncomment line with child.stdin.end(); it only ends whithout any reaction
The one thing you need to make the script work was to add:
process.stdin.pipe(child.stdin);
If you added this before the child.stdin.write, that would solve half the problem. The other half had to do with the Java side. If the java program is not launched from a console by typing java HelloWorld, then Console will return null thus you will get a NullPointerException if you tried to use Console.readLine. To fix, this use BufferedReader instead.
Change your script to this:
const spawn = require('child_process').spawn;
const child = spawn('java', ['HelloWorld'], {
stdio: ['pipe', process.stdout, process.stderr]
});
process.stdin.pipe(child.stdin);
setTimeout(() => {
child.stdin.write('tratata\n');
}, 1000);
Then change your java code to this:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class HelloWorld {
public static void main(String[] args) throws IOException {
System.out.println("started");
try(BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {
for (String line = console.readLine(); line != null; line = console.readLine()) {
System.out.printf("Your sentence: %s\n", line);
}
}
}
}
See:
NodeJS Spawn Command
System.console() returns null
I try to route on TomTom maps and get a callback from the routing method.
So I made up a Java Application in JavaFx and showed the TomTom Map on my webview from JavaFX.
Now my issue: I do call a method in Javascript from JavaCode and want to get the response from the routing method, but this takes time and is asynchronous. And I just get the Promise Object from javascript and not the response...
I changed the javscript functions and don't work with promises anymore.
Edited Code:
JavaCode:
package application;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Properties;
import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class Main extends Application{
static JSObject window;
static Stage primaryStage;
public void start(Stage primaryStage) {
try {
Browser browser = new Browser();
browser.getWebEngine().getLoadWorker().stateProperty()
.addListener((obs, oldValue, newValue) -> {
if (newValue == State.SUCCEEDED) {
window = (JSObject) browser.getWebEngine().executeScript("window");
System.out.println("Now call gogo");
System.out.println("gogo Output: " + window.call("gogo"));
WebController webControl= new WebController(browser, window);
window.setMember("clickController", webControl);
System.out.println("First it will go over here and print this");
LocalDate date = LocalDate.now();
try {
FileWriter fw = new FileWriter("output/"+date+".csv", true);
BufferedWriter bw = new BufferedWriter(fw);
bw.append(LocalTime.now() + ";" + delay + "\n");
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Scene scene = new Scene(browser, Color.web("#666970"));
primaryStage.setTitle("TestApplication");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Javascript:
function gogo(){
var data = goTask(function(data) {
console.log(data.summary.totalDistanceMeters);
clickController.print("after all that java stuff it will invoke this syso")
clickController.print("output Routing function: " + data.summary.totalDistanceMeters);
clickController.print("gogo output with invoking java from javascript");
return data;
});
return data;
}
function goTask(call){
function callback(d){
call(d);
}
routeMe(callback);
function routeMe(callbackFunc){
var points = [ [48.7061643,9.1664228], [48.7322085,9.0489835] ];
var service = new tomtom.services.RoutingService("'ApiKey'");
var options = {
includeTraffic: true
// avoidTolls: true
};
service.getRoute(points, options,callbackFunc);
}
}
Output:
Now call gogo
gogo Output: undefined
First it will go over here and print this syso
WebController Syso: after all that java stuff it will invoke this
WebController Syso: output Routing function: 9419
WebController Syso: gogo output with invoking java from javascript
The problem is that Java does not wait on Javascript...
Can anyone help me?
Edit:
#Bonatti I am running it on
ScriptEngineFactory getEngine --> Oracle Nashorn
ScriptEngine getLanguage --> ECMAScript
Right now you are returning a Promise to Java, which doesn't know what to do with it. It won't wait for the promise to be fulfilled, and since there's no way of it interpreting the promise not much happens.
You can only handle this promise within Javascript, with something like .then( ... ), wherein you actually handle the result you expect right now (the delay).
Forcing the promise to be used synchronously will not work, it would be the same issue if you would want to handle your function result synchronously within Javascript (Call An Asynchronous Javascript Function Synchronously).
Try #Evan Knowles' answer here but with your callback instead:
We're going to set a listener for the successful state - basically we're going to inject a Java class into the JavaScript and have it call us back. Let's create a WebController that checks what is passed in and prints out the ID
How to catch return value from javascript in javafx?
I do not know the tomtom service. But from reading your code return new Promise is working as intended, as you are receiving the Promise
I would suggest having another function to receive the route then use a SOAP to read the data into your application
i just completed a web based chat application based on ajax/php. But the problem with this app is that it has to continuously poll server to check for new messages, which in turn overloads the server if many people are using this app simultaneously.
now i want to implement a socket based chat app in JavaScript. I know there is no support for sockets in JavaScript so i decided to use "Flash as a socket gateway for JavaScript" i am using Linux and and new to flash. can someone help me with how to achieve this.
basically,
1) I want to make a small SWF object that just handles socket logic(minimum width and height so i can hide it easily with -ve margin.
2) I want to access this swf object with JavaScript
i got a code for simple socket in actionscript (from internet) but i cannot get it to compile using mxmlc(free flash compiler).
heres the code...
myXML = new XMLSocket;
myXML.onConnect = handleConnect;
myXML.onXML = handleXML;
myXML.onClose = handleDisconnect;
myXML.connect("http://www.yourServer.com", 12345);
function handleConnect(connectionStatus){
connectionStatus ? trace("Connected.") : trace("Connection failed.");
}
function handleXML(xmlObject){
trace("Object recieved:: "+xmlObject);
}
function sendXML(textToSend){
myXML.send(new XML('"+textToSend+""));
}
function handleDisconnect(){
trace("Connection lost.");
}
function closeConnection(){
trace("Closing connection to server.");
myXML.close();
}
i got a better code but this also does not compile
package
{
import flash.errors.*;
import flash.events.*;
import flash.net.Socket;
public class ChatSocket extends Socket
{
public var host:String;
public var port:uint;
private var socket:Socket;
public static var SOCK_CONNECTED:String = "onSockConnect";
public static var SOCK_IOERROR:String = "onSockIOError";
function ChatSocket(h:String, p:uint)
{
host = h;
port = p;
socket = this;
super(host, port);
initListeners();
}
public function sendMessage(str:String):void
{
if(connected)
{
socket.writeUTFBytes(str + "\n");
}
else
{
trace("Not connected, message not sent!");
}
}
public function readMessage():void
{
if(connected)
{
var str:String = socket.readUTFBytes(socket.bytesAvailable);
trace("Socket Server Response: " + str);
}
else
{
trace("No message read, not connected!");
}
}
private function initListeners():void
{
socket.addEventListener(Event.CLOSE, closeHandler);
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,
ioErrorHandler);
}
private function closeHandler(event:Event):void
{
trace("Connection to [" + host + "] closed");
}
private function ioErrorHandler(event:IOErrorEvent):void
{
dispatchEvent(new Event(SOCK_IOERROR));
}
private function connectHandler(event:Event):void
{
trace("Connected to [" + host + "]");
dispatchEvent(new Event(SOCK_CONNECTED));
}
private function socketDataHandler(event:ProgressEvent):void
{
readMessage();
}
}
}
var sock:ChatSocket;
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
ERROR IS:
localhost bin]$ ./mxmlc ChatSocket.as
Loading configuration file /home/lk/Documents/flex_sdk_3.4/frameworks/flex-config.xml
/home/lk/Documents/flex_sdk_3.4/bin/ChatSocket.as: Error: A file found in a source-path can not have more than one externally visible definition. ChatSocket;sock;ioError;connected
You may wish to check out gimite's web-socket-js. This is a socket gateway that conforms to the work-in-progress Web Socket API, so in future as browsers implement native WebSocket it will automatically switch over to the Flash-free alternative.
The following code lies outside the class and package {} blocks. That is not allowed.
var sock:ChatSocket;
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
Declare a document class (that extends Sprite) and move ioError and connected methods to it. Make sock an instance variable instead of a local variable and add the declaration part of sock into its constructor.
//DocClass.as
package
{
public class DocClass
{
private var sock:ChatSocket;
public function DocClass()
{
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
}
private function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
private function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
}
}