I have a JAVA function like this in a .jar.
I want to call this function in R, but I am not being able to use the "main" method. Does anyone know how to call this "main" method using rJAVA to produce results?
I have read in a place that I need to create a separate static method in the JAVA code to access it, is that true?
public class CountJTrees
{
public static void main(String[] args)
{
try
{
Network<String,Object> g = Graphs.read();
try
{
JTree<String> jjt = new JTree<String>(g);
System.out.println(jjt.enumerate());
}
catch(GraphNotDecomposableException e)
{
System.out.println(0);
}
}
catch (Exception e)
{
System.err.println("Caught CountJTrees.main()");
e.printStackTrace();
}
}
}
Let's say you have structure like this:
.
|-- Manifest.txt
`-- src
`-- somepackage
`-- StringTest.java
and file StringTest.java contains:
package somepackage;
public class StringTest {
public String changeString(String str) {
return "I have changed the string: " + str;
}
public static void main(String [] arg) {
System.out.println(new StringTest().changeString("Hello"));
}
}
You can easily build JAR file. With Manifest.txt file
Manifest-Version: 1.0
Main-Class: somepackage.StringTest
following way:
> jar cfm test.jar Manifest.txt -C target somepackage/StringTest.class
# execute JAR - just to test it works as expected
> java -jar test.jar
I have changed the string: Hello
Once your JAR is working as expected, you can run it in R
> export CLASSPATH=./test.jar
> R
R version 3.6.1 (2019-07-05) -- "Action of the Toes"
Copyright (C) 2019 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin15.6.0 (64-bit)
...
...
...
> library(rJava)
> .jinit()
> obj <- .jnew("somepackage.StringTest")
> s <- .jcall(obj, returnSig="V", method="main", c("Hello", "Hello") )
I have changed the string: Hello
>
Related
I'm trying to transpose to vue.js this simple html page add.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<input type="button" value="Add" onclick="callAdd()" />
<script>
function callAdd() {
const result = Module.ccall('Add',
'number',
['number', 'number'],
[1, 2]);
console.log(`Result: ${result}`);
}
</script>
<script src="js_plumbing.js"></script>
</body>
</html>
which calls the Add function defined in add.c :
#include <stdlib.h>
#include <emscripten.h>
// If this is an Emscripten (WebAssembly) build then...
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#ifdef __cplusplus
extern "C" { // So that the C++ compiler does not rename our function names
#endif
EMSCRIPTEN_KEEPALIVE
int Add(int value1, int value2)
{
return (value1 + value2);
}
#ifdef __cplusplus
}
#endif
and converted to js_plumbing and js_plumbling.wasm files through the command:
emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s
ENVIRONMENT='web','worker'
In console of google chrome I get these errors:
GET http://localhost:8080/dist/js_plumbing.wasm 404 (Not Found) # js_plumbing.js?2b2c:1653
Where in js_plumbing_js :
// Prefer streaming instantiation if available.
function instantiateAsync() {
if (!wasmBinary &&
typeof WebAssembly.instantiateStreaming === 'function' &&
!isDataURI(wasmBinaryFile) &&
typeof fetch === 'function') {
fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { // <---------------!!!
var result = WebAssembly.instantiateStreaming(response, info);
return result.then(receiveInstantiatedSource, function(reason) {
// We expect the most common failure cause to be a bad MIME type for the binary,
// in which case falling back to ArrayBuffer instantiation should work.
err('wasm streaming compile failed: ' + reason);
err('falling back to ArrayBuffer instantiation');
instantiateArrayBuffer(receiveInstantiatedSource);
});
});
} else {
return instantiateArrayBuffer(receiveInstantiatedSource);
}
}
In Google Chrome: createWasm # js_plumbing.js?2b2c:1680
line 1680 of js_plumbing.js:
instantiateAsync();
in Google Chrome: eval # js_plumbing.js?2b2c:1930
line 1930 of js_plumbing.js:
<pre><font color="#4E9A06">var</font> asm = createWasm();</pre>
And many other errors related to wasm :
So... how should I modify the callAdd() method in Result.vue in order to correctly execute the Add function in js_plumbing.js and in js_plumbing.wasm files?
methods: {
callAdd() {
const result = Module.ccall('Add',
'number',
['number', 'number'],
[1, 2]);
console.log('Result: ${result}');
}
}
Updates:
1 update)
I compiled the add.c with this command:
emcc add.c -o js_plumbing.mjs -s EXTRA_EXPORTED_RUNTIME_METHODS=
['ccall','cwrap'] -s ENVIRONMENT='web' .
Then created a js_plumbing.js file :
. import wasm from './js_plumbing.mjs';
const instance = wasm({
onRuntimeInitialized() {
console.log(instance._addTwoNumbers(3,2));
}
}) .
Doing npm run dev:
Failed to compile.
./src/components/js_plumbing.mjs 3:25
Module parse failed: Unexpected token (3:25)
You may need an appropriate loader to handle this file type, currently
no loaders are configured to process this file.
See https://webpack.js.org/concepts#loaders
|
| var Module = (function() {
> var _scriptDir = import.meta.url;
|
| return (
Update 2)
I solved the 404 error by putting the wasm file into a /div subfolder within the same folder of the index.html file.
Now I’m facing this problem: “Cannot read property ‘ccall’ of undefined”
But I compiled the add.c file, creating js_plumbing.js and js_plumbing.wasm files, with this command, which exports the methods ‘ccall’ and ‘cwrap’ :
emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=[‘ccall’,‘cwrap’] -s ENVIRONMENT=‘web’,‘worker’
3° Update)
I "solved" through a sort of an hack, which I do not like at all.
This is the Result.vue file:
<template>
<div>
<p button #click="callAdd">Add!</p>
<p>Result: {{ result }}</p>
</div>
</template>
<script>
import * as js_plumbing from './js_plumbing'
import Module from './js_plumbing'
export default {
data () {
return {
result: null
}
},
methods: {
callAdd () {
const result = js_plumbing.Module.ccall('Add',
'number',
['number', 'number'],
[1, 2]);
this.result = result;
}
}
}
</script>
which is exactly the same as the one used before
The only thing I've done to make it working, is to add export to the definition of Module in js_plumbing.js :
js_plumbing.js
// Copyright 2010 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT
license and the
// University of Illinois/NCSA Open Source License. Both these
licenses can be
// found in the LICENSE file.
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of
the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module =
{};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
export var Module = typeof Module !== 'undefined' ? Module : {};
But, as I said, I do not like this hack.
Any suggestions on how to make the Module exportable, thus importable, without manually adding 'export' in js_plumbing.js file?
First, the 404 error should be addressed. Does file /dist/js_plumbing.wasm exist? I've needed to copy .wasm files manually in the past because some automatic build systems (like Parcel) currently don't.
You can build with the MODULARIZE option to import into your build system.
addTwoNumbers.c
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int addTwoNumbers(int value1, int value2)
{
return (value1 + value2);
}
build command
$ emcc -o dist/addTwoNumbers.js -s MODULARIZE=1 src/addTwoNumbers.c
Vue Implementation
import myMathModule from './js_plumbing';
let instance = {
ready: new Promise(resolve => {
myMathModule({
onRuntimeInitialized() {
instance = Object.assign(this, {
ready: Promise.resolve()
});
resolve();
}
});
})
};
export default {
data () {
return {
result: null
};
},
methods: {
callAdd(a, b) {
instance.ready
.then(_ => this.result = instance._add(a, b));
}
}
};
Use the onRuntimeInitialized method to detect when the WASM module is ready. Your exported functions will have an underscore in front of them.
require() could possibly be used in place of import:
const wasmModule = require('./addTwoNumbers.js');
...
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>
I have a JavaScript code that I need to get into console application. The script works fine trough cmd but I want to make a console application out of it so its more user friendly. Can someone explain to me how I can write this code in console application or attach it inside the console application with links. I am new to console application so I apologize if I ask anything stupid :-)
When I use it trough cmd then I do the following;
- Run cmd.
- Type "cd downloads" and press enter.
- Type "cscript /nologo process.js log.txt 100 200" and press enter.
- Then I will get a list in the cmd window and I need to have process.js and log.txt in the download folder to make this work.
if(WScript.Arguments.Count() < 3)
{
WScript.Echo("Usage: cscript process.js <filename> <lower_value> <upper_value>");
WScript.Quit();
}
var filename = WScript.Arguments.Item(0);
var lowerBound = parseInt(WScript.Arguments.Item(1));
var upperBound = parseInt(WScript.Arguments.Item(2));
WScript.Echo("Here is the data from the file associated with the text 'verdi', where the");
WScript.Echo("number following 'verdi' is above " + lowerBound + " and below " + upperBound);
var fso = new ActiveXObject("Scripting.FileSystemObject")
var file = fso.OpenTextFile("log.txt", 1, false);
var lines = file.ReadAll().split('\r');
var failed = 0;
for(var idx in lines)
{
try
{
if(lines[idx].indexOf('verdi') > 0)
{
var tmp = lines[idx];
var regex = /verdi\s*\=\s*(\d+)/;
var result = regex.exec(tmp);
var num = parseInt(result[1]);
if(num >= lowerBound && num <= upperBound)
{
WScript.Echo(num);
}
}
}
catch(ex)
{
failed++;
}
}
if(failed > 0)
{
WScript.Echo("WARNING: one or more lines could not be processed!");
}
I have made this code in console application but it doesent work properly. I can choose the values and get the cmd to run. But I don't get the results in the window and print the result to a document.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
private static object cmd;
private static int verdi;
private static int s;
private static int d;
public static object WScript { get; private set; }
static void Main(string[] args)
{
//Choose lower and upper value
Console.WriteLine("Choose a lower and upper value:");
string value = Console.ReadLine();
//Choose file
Console.WriteLine("Choose a file to scan:");
string file = Console.ReadLine();
//Run the javascript code
Console.WriteLine("cd downloads");
Console.WriteLine("cscript /nologo process.js {0} {1} > mydata.txt", file, value);
string command = Console.ReadLine();
Console.WriteLine("Press any key to start scan");
System.Diagnostics.Process.Start("cmd.exe", "/C" + command);
//Quit Console Application
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
}
Console.WriteLine only prints strings. It doesn't allow you to execute commands.
You could try this instead:
string command = $"cscript /nologo c:/downloads/process.js c:/downloads/{file} {lowerValue} {upperValue} > mydata.txt");
System.Diagnostics.Process.Start($"cmd.exe /C {command}");
There is also an error in process.js. That script always reads from log.txt and ignores the filename.
But why are you using two programs here? You could just have all the code in one file. And why use JavaScript for one and C# for the other?
I am working on a project that requires that a Java class be called from a piece of Javascript that was executed by a separate piece of Java code. It did originally work in Java 7.51 but it needs to work in Java 1.6.0_27 as well but fails with a function importclass must be called with a class error message.
The two JARs were generated through Eclipse Indigo using the Export > JAR command.
I created a simple MCVE as below to demonstrate the problem. The stack trace from executing with the following command line...
java -cp Sanity.jar;SanityCheck.jar -jar SanityCheck.jar
...is the following:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: Function importClass must be called with a class; had "[JavaPackage com.sanity.Sanity]" instead. (<Unknown source>#1) in <Unknown source> at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at javax.script.AbstractScriptEngine.eval(Unknown Source)
at com.sanity.SanityCheck.<init>(SanityCheck.java:22)
at com.sanity.SanityCheck.main(SanityCheck.java:52)
Exception in thread "main" java.lang.NullPointerException
at com.sanity.SanityCheck.invoke(SanityCheck.java:31)
at com.sanity.SanityCheck.main(SanityCheck.java:53)
Can anyone see where I am going wrong here?
Sanity.java (in its own JAR of the same name)
package com.sanity;
public class Sanity {
public Sanity() {}
public void doCheck() {
System.out.println("Sanity Check Passed!");
}
}
SanityCheck.java (in its own JAR of the same name)
package com.sanity;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class SanityCheck {
private Invocable invoker;
public SanityCheck(String script) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval(script);
invoker = (Invocable) engine;
} catch (ScriptException e) {
e.printStackTrace();
}
}
public void invoke() {
try {
invoker.invokeFunction("run");
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Sanity.js")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
SanityCheck check = new SanityCheck(builder.toString());
check.invoke();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sanity.js
importClass(Packages.com.sanity.Sanity);
function run() {
var sanObj = new Sanity();
sanObj.doCheck();
}
I have good news: the problem has nothing to do with your Java or JavaScript code. It has to do with the effect of the command:
java -cp [...] -jar <jar-file>
When executing that command, the -cp argument is ignored, and the <jar-file> is used as the entire classpath.
From the Java 6 documentation for the -jar option to the java tool:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So a version of your command that would work is:
java -cp Sanity.jar;SanityCheck.jar com.sanity.SanityCheck
I reproduced your example with the following directory structure, without modifying your code:
Sanity.js
com/
sanity/
Sanity.java
SanityCheck.java
... and then ran the following command from the top-level directory:
$ /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/javac com/sanity/*.java && /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/java -classpath . com.sanity.SanityCheck
... and got
Sanity Check Passed!
The error was down to the JAR file that was being called from the Javascript was compiled against Java 7, not Java 6. A quick test trying to run a main method in Eclipse soon revealed this.
A quick recompilation of the JAR file and now it works.
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}