Good morning. I am working on a project that uses Karate Standalone. I am completely new to Karate to excuse my lack of knowledge here.
The standalone karate jar is executed with the '-m' command line parameter to start a mock.feature. The mock.feature references a utils class that is built on 'org.springframework.amqp'.
The problem is that the karate.jar startup fails with a Command Line Execution Exception due to external library 'org/springframework/amqp/rabbit/connection/ConnectionFactory'
api1_mock_test.feature
Feature: API1 Mock Test
Background:
* def RabbitUtils = Java.type('utils.RabbitUtils')
.
.
Our RabbitUtils is just a java class that imports org.springframework.amqp external libraries to provide functions to interact with a Rabbit AMQP broker e.g. connect, receive, publish, purge etc. When built and run in IntelliJ all works ok. The POM reference in the project is:
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
Does the Karate standalone jar have some way of referencing external libraries? The classpath parameter is set to reference our workspace '.\target\test-classes' and contains the RabbitUtils.class file.
The current execution from workspace root looks like this:
java -jar C:\intuit\karate-0.9.3.RC2.jar -cp .\target\test-classes -p 6868 -m .\src\test\java\mocks\api1_mock_test.feature
08:57:05.122 [main] INFO com.intuit.karate.Main - Karate version: 0.9.3.RC2
08:57:05.891 [main] ERROR com.intuit.karate - server-side background init failed - api1_mock_test.feature:4
Exception in thread "main" picocli.CommandLine$ExecutionException:
-unknown-:4 - org/springframework/amqp/rabbit/connection/ConnectionFactory
Thank you!
Thanks for asking this, and I think I've figured out a way to do this which opens up a lot of great possibilities. The solution is to use Java first-principles, and not use the -jar option. The Karate command-line-app (or CLI) class happens to be com.intuit.karate.Main. I'm going to provide a demo here of using SikuliX. First, the feature file test.feature:
Feature: sikuli test
Background:
* def Screen = Java.type('org.sikuli.script.Screen')
Scenario:
* def s = new Screen()
* def c = s.capture()
* c.getFile('.')
And with the karate.jar and sikulixapi.jar in the same folder on the command line, this works (for windows, use ; instead of : as the "path separator"):
java -cp karate.jar:sikulixapi.jar com.intuit.karate.Main test.feature
For those looking to customize the classpath for the Visual Studio Code "Karate Runner" extension, please refer this: https://github.com/intuit/karate/wiki/Karate-Robot-Windows-Install-Guide#change-command-line-settings
Also see: https://stackoverflow.com/a/58398958/143475
For those who really don't want to compile Java but need to use some JVM libraries, it is possible via pure JS, (but hard to troubleshoot and debug): https://stackoverflow.com/a/65035825/143475
Related
I am writing an algo to analyze market data in Java, to visualize my data i'd like to make use of an existing charting library from tradingview. This free charting library runs on nodeJS.
I'm having a lot of trouble understanding how to populate it with my data resulting from my algorithm.
For example my Java code returns a "List< Candlestick >" object, how do i send this to the Javascript code running on the nodeJs ?
if someone would be so kind to give some global directions in how to approach this it would be very much appreciated.
My assumption here is that you have java code and the result you want to display is on nodejs.
While at this moment calling data from the API is suggested, also there is one more option we can use to solve your problem. This is a good case of polyglot programming. I have used graalvm.
Installation via sdkman
GraalVM
sdk install java 21.1.0.r11-grl
NodeJS
gu install nodejs
Both Main Projects are located here https://gitlab.com/graalvm-java-to-nodejs
Java Project (has method which return a list)
NodeJS Project(loads Java Class in NodeJS and call method on class reference to get the list)
Add any code to java library in my case I have a class which just return list of Point as given below:
public class GraphData {
public List<Point> getPoints() {
return List.of(new Point(1, 1), new Point(3, 5));
}
}
where Point is a POJO class to hold (x, y) value.
Clone this java project https://gitlab.com/graalvm-java-to-nodejs/graalvm-simple-java and execute ./gradlew clean build this should give you a executable jar which can be executed java -jar file.jar command.
Now, clone https://gitlab.com/graalvm-java-to-nodejs and install dependencies npm install then execute
node --jvm --vm.cp=/home/ashish/IdeaProjects/graavlvm/java-lib-gvm/build/libs/java-lib-gvm-1.0-SNAPSHOT.jar bin/www
Relevant code which interacts with java is as below:
var GraphDataJavaRef = Java.type('in.silentsudo.GraphData');
var graphData = new GraphDataJavaRef();
var data = graphData.getPoints();
in.silentsudo.GraphData class is loaded from the jar file which is provided to node program with argument named --jvm --vm.cp path/to/file.jar
Once you navigate to localhost:3000, you should see
Express Tutorial
Welcome to Express Tutorial
Response from Java class
[Point{x=1, y=1}, Point{x=3, y=5}]
actually I have a problem with incuding an antlr4 grammar in my angular project written in visual studio code. I could create the grammar itself (the .g4 file) and there was automatically built an .antlr folder, in which are the following files:
However, these are only the java files and I need for the browser the javascript version. At this point I am not sure how to continue.
Apparently, VS Code automatically does something like this behind the scenes:
java -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool Grammar.g4
which generates the default target language (Java).
To let it generate Javascript sources, do something like this from your terminal where your grammar is located:
java -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -Dlanguage=JavaScript Grammar.g4
Assuming you have antlr-4.7.2-complete.jar in the same folder as your Grammar.g4 file.
You should be able to change this settting in antl4.generation -> language=JavaScript
I have an application where the output is written into a file (.py) by using javascript.
I'm using this application to write python script into the file. Now I want to run the python script automatically on cmd(Windows) right after the output was written.
Is there a way to do so ? Is it possible without using "NodeJS"
So apparently everything happens with a single click on the application.
Thanks.
Node js provides the child process module,
which you can use to basically spawn a child process from your js application.
since you have not shared any source code so i am not sure what your specific use case is but a basic way of spawning python script would be like this.
import { spawn } from 'child_process';
let scriptPath = './script.py' // path to your python script
var script = spawn('python', ['-u', scriptPath, arg1, arg2]); // arg1,arg2 can be any command line arguments required by your script or if not needed you can skip them.
script.stdout.on('data', data => {
console.log('Data: ', data.toString());
// implement your functionality here
});
you can similary bind on close and error events to your script and implement the functionality accordingly.
Why not storing your script in a script.py file? Why do you use .txt at all? With CMD and Python installed you should easily run .py scripts with a command line "python path/to/script.py", shouldn't you?
Edit: For checking out how to execute python on Node JS just use Google! Google is your friend! "execute python with node js" threw me this article: How to call python script from NodeJs
I have a Rails application that needs to run a node script. I imagine that using the ExecJS gem is the cleanest way to run JavaScript from a Rails app. However, so far, ExecJS has proved to be very frustrating to use.
Here is the script I need to run:
// Generated by CoffeeScript 1.7.1
(function() {
var PDFDocument, doc, fs;
fs = require("fs");
PDFDocument = require('pdfkit');
doc = new PDFDocument;
doc.pipe(fs.createWriteStream('output.pdf'));
doc.addPage().fontSize(25).text('Here is some vector graphics...', 100, 100);
doc.save().moveTo(100, 150).lineTo(100, 250).lineTo(200, 250).fill("#FF3300");
doc.scale(0.6).translate(470, -380).path('M 250,75 L 323,301 131,161 369,161 177,301 z').fill('red', 'even-odd').restore();
doc.addPage().fillColor("blue").text('Here is a link!', 100, 100).underline(100, 100, 160, 27, {
color: "#0000FF"
}).link(100, 100, 160, 27, 'http://google.com/');
doc.end();
}).call(this)
From my Rails console, I try this:
[2] pry(main)> file = File.open('test.js').read
[3] pry(main)> ExecJS.eval(file)
ExecJS::ProgramError: TypeError: undefined is not a function
from /Users/matt/.rvm/gems/ruby-2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:68:in `extract_result'
Note that I can run this script successfully using 'node test.js' and I am also able to run run the script using the backtick syntax Ruby offers:
`node test.js`
But that feels like a hack...
It's erroring out because require() is not supported by EvalJS. 'require' is undefined, and undefined is not a function. ;)
I'm not sure of the answer but maybe you need to precise the exec_js_runtime environment variable to be node.
Something like ENV['EXECJS_RUNTIME'] = 'Node' You can try to put it in the config/boot.rb or just to define the EXECJS_RUNTIME in your environment, something like export EXECJS_RUNTIME=Node
Hope it helps
ExecJS people say use commonjs.rb https://github.com/cowboyd/commonjs.rb
Why can't I use CommonJS require() inside ExecJS?
ExecJS provides a lowest common denominator interface to any
JavaScript runtime. Use ExecJS when it doesn't matter which JavaScript
interpreter your code runs in. If you want to access the Node API, you
should check another library like commonjs.rb designed to provide a
consistent interface.
But this doesn't work basically. The require acts completely erratically - I had to execute npm -g install pdfkit fs between env = and env.require in
require 'v8'
require 'commonjs'
env = CommonJS::Environment.new(V8::Context.new, path: ::Rails.root )
env.require 'script'
for the module lookup to work O.o and if I tried pointing path to the node_modules folder then it would be impossible for the gem to find script (not to mention that the #new and require are basically the only documented methods - only methods afaik - and #new is misdocumented :P)
Your options as far as I can tell:
system(node ...) - you can use Cocaine to escape some gotcha's (piping output, error handling, performance tweaks, ...) and run a cleaner syntax - this is not as bad as it looks - this is how paperclip does image postprocessing (imagemagick system package + cocaine) so I guess it's very stable and very doable
expose to web api and run a separate worker on a free heroku dyno for example to do this and similar stuff you want to do with node libs
use prawn :)
Get rid of ExecJS and anything that depends on ExecJS. I tried all the other suggestions, but this actually fixed it.
ES6 has been around since 2015. Any tool worth using supports it by now. MICROSOFT EDGE supports it by now. Seriously.
I have installed Node from:
Node
and run this in cmd:
npm install twilio
I then tried the example code provided by Twilio:
var accountSid = 'MyAccountSidHere';
var authToken = "MyAccountAuthTokenHere";
var client = require('twilio')(accountSid, authToken);
client.sms.messages.create({
body: "Jenny please?! I love you <3",
to: "SomeNumber",
from: "MyNumber"
}, function(err, message) {
process.stdout.write(message.sid);
});
Saved this to MyFile.js file and double clicked it.
I get the error message:
ReferenceError: require is not defined
This is my first encounter with JavaScript and I found a lot of similar questions, but have not been able to solve this.
I am to use this with QML, so I want to load it using:
import "MyFile.js" as MyFile
then call the javascript code as a function.
I've read a little into QML and I don't see how you could use a node.js module in QML. QML is used as a language where QT is the JavaScript engine and node.js is a server-side Javascript engine.
The require() function is a core function of node.js which is part of the engine. It's not something language-specific just like the window object in browser-based Javascript is not something in the Javascript language.
As I said in my comment, you should check out what node.js actually is: a server-side JavaScript engine, which executes JavaScript files. It is not a framework which you could load into another engine like QT.
Your code will run if you use it like this from the command-line:
node MyFile.js
I doubt this is helpful for your use-case as a QML import though.