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}]
Related
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
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 am trying to use string similarity inside Google App Script, however it is not entirely clear to me how to get it working inside App Script, I get multiple errors, such as "require" is not defined, as another note, the module itself appears to have a dependency.
My final goal is to use this script to match string score between one array with strings full of typos to one with correct strings all within App Script. This is my failed code.
function matchEmails() { var doc =
SpreadsheetApp.openById(("ID"));
var ts = doc.getSheetByName("dir"); var source =
doc.getSheetByName("data"); var names =
source.getDataRange().getValues(); var data =
ts.getDataRange().getValues(); var arr = []; var arr2 = []; var
arr3 = []; var arr4 = [];
for (i=0; i<names.length; i++) {
for (j=0; j<data.length; j++) {
stringSimilarity.compareTwoStrings(names[i][0], data[j][0]); Logger.log(stringSimilarity);
/*
var n = data[j][0].split();
for (N=0; N<n.length; N++) {
arr2.push(n[N].charAt(0));
}
var string2 = arr2.join("");
var arr2 = [];
if (names[i][0] === data[j][0]) {
arr.push([data[j][1]]);
} */ //I want to replace this blanked out code with String >similarity.
if (string === string2) {
arr.push([data[j][1]]);
arr3.push([i+1]);
arr4.push([data[j][0]]);
}
} } for (i = 0; i<arr.length; i++) {
source.getRange(arr3[i],6).setValue(arr[i]);
source.getRange(arr3[i],7).setValue(arr4[i]); } }
Your GAS project is not a Node.js app, so the above will not work. While both Google Apps Script and Node use JavaScript, they provide different runtime environments for executing JS code. In GAS, the environment is a closed ecosystem on Google Servers that end users don't know anything about.
In Node, the runtime consists of V8 (JS engine) and C++ add-ons that expose low-level APIs (access to the file system, etc.). The library you referenced is an NPM package created for Node.js. Installing the package via NPM will make it available for Node projects, but don't think it will magically appear on Google servers as well.
You must either use GAS-specific versions of these dependencies, or, if they don't exist, refactor the source code to make it compatible with GAS (Node and GAS use different ECMAScript versions, so some latest features like arrow functions will break your GAS code).
For example, here's lodash for GAS
https://github.com/contributorpw/lodashgs
Using libraries in GAS
https://developers.google.com/apps-script/guides/libraries
P.S. In GAS, all ".gs" files share the same namespace, so calling 'require' function is redundant. If you want to mimic this behavior, you'll still need to write your own require function.
I wrote up some guidance on packaging up an npm module for usage in Apps Script in this article.
tl;dr is to create an index.js with the following in a new directory:
import {compareTwoStrings, findBestMatch} from 'string-similarity';
export {compareTwoStrings, findBestMatch};
and then run the following in that directory:
npm init -y
npm install --save-dev string-similarity
npx esbuild index.js --bundle --global-name=stringSimilarity --outfile=StringSimilarity.js
You can then copy the contents of StringSimiliarity.js into a new .gs file in the Apps Script editor. The exported functions will be usable from your own Code.gs as stringSimilarity. compareTwoStrings() and stringSimilarity.findBestMatch().
(In case you'd rather not bundle it yourself, the output of the esbuild process for string-similarity can be found in this gist. But the general steps should apply to most npm modules that don't require a Node or browser-specific runtime environment.)
Google Apps Script files by default have access to Google APIs, such as the Spreadsheet Service in the G Suite Services:
https://developers.google.com/apps-script/reference/spreadsheet/
A GAS project (so scripts in that project) doesn't by default have access to Node.js or any other frameworks. However, a GAS project can include another GAS project by reference as a library. In the GAS Script Editor, use menu Resources > Libraries... to add an external GAS project as a library by setting the source project's project key (and some other source project properties).
So if you have a Javascript that depends on external resources (like Node.js) by require then if you can find an external GAS project that provides the same services with the same API you can provide it as a library to the script. You omit the require statements from the original script as they're replaced by the GAS library dependency configuration I mentioned.
If your original script and its dependencies are all open source you could create GAS projects for each level of dependencies in the originals. You can already find some popular JS frameworks scripts available as GAS libraries.
GAS also allows packaging external resources as Web apps and other package formats. They can be used with corresponding techniques, and some of them found already available from other developers.
Building upon the answer of Jeff Posnick, note we can use https://esbuild.github.io in the same simple way to bring a complete library into Google Apps Script. For example with Ramda :
npm init -y
npm install --save-dev ramda
cp ./node_modules/ramda/dist/ramda.js .
npx esbuild ramda.js --minify --bundle --global-name=R --outfile=R.js
Then copy the contents of R.js into a new .gs file in the Apps Script editor.
Now you can use ramda in your code, for example:
const seventeen = R.add(7)(10);
An easy workaround is to use JavaScript's Eval function to call an external library hosted online
i. e. eval(UrlFetchApp.fetch('http://path.to/external/javascript.js').getContentText());
This won't work if the library itself depends on other modules which aren't available in the GAS runtime, but for certain libraries it can be a simple solution.
Im having a nodeJS &express application which you can use like following:
var myNodeApp = require('myNodeApp');
my question is if there is a way to add to this application a new module/file by code
something like
var myNodeApp = require('myNodeApp');
myNodeApp.addModule("newModule")
or something like
myNodeApp.addFile("/path to the file")
That in run-time I will be able to read the content.
Im not talking about the typical import export(or npm install) module inside my node project(this is obvious) , I want that by code the developer(which use my node app) will be able to add file/module to my code which In RT I will be able to use.
Is it possible in node.js ?
I try to find referance about this topic without success...
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.