Running java code in a docker container using dockerode - javascript

I want to send some java code as a string to an API to then run it in a docker container and return the console output, I have managed to do it with Python but as java first needs to be compiled then ran I'm unsure how to implement the language.
currently using the python image but I am not too familiar with java and im unsure how to approach it.
my environment is node using typescript and im using the dockerode module.
let container = await docker.createContainer({
Image: 'python',
Tty: true,
Cmd: ['/bin/bash'],
StdinOnce: true
});
I'm able to pass the string directly to the container by adding it to the Cmd after running python but not sure how I would pass a string into a file then compile and run it.
var options = {
Cmd: ['python', '-c'],
AttachStdout: true,
AttachStderr: true,
};
options.Cmd.push(code);
let exec = await container.exec(options);
I just have a listener to capture the output stream which can be used for later
stdout.on('data', (chunk: any) => {
let data = chunk.toString('utf8').split(/\r?\n/).filter((str: string) => {return str.length});
output = data;
})
any advice on which image to use along with how to pass the code through to get the output would be appreciated.

Depending on what you're trying to achieve, you may want to compile your code inside the docker container or not, or bind mount or push the files into the container.
This example simply mounts (binds) the current working directory inside the container and calls javac (or java). The resulting .class file would appear in your current directory (only works on systems where your terminal is on the host). You could then re-run the same command with java and the class name to execute it.
docker.run(
'java:8',
['javac', 'yourclass.java'],
process.stdout,
{
HostConfig: {
AutoRemove: true,
Binds: [
`${process.cwd()}:/app`
]
},
WorkingDir: '/app'
}
)
Your question says that you "want to send some java code as a string to an API", although exactly what qualifies as "sending a string to an API" is not clear. Along the lines of what you did with Python, you could echo '${code}' > myclass.java, although you risk running into escaping issues with the quotation marks.
An alternative approach is to create the container and then container.putArchive('yourclass.java', options). I don't know if this qualifies as "sending a string".

Related

how to load json file from geth

maybe it is because I am not handy with js, but how can I load a .json file from geth console? I want this in order to avoid the clumpsy way of copy-paste each raw abi content for each one of the contracts var abi_1 = [...]; var abi_2 = [...]; .... I know the console is javascript, so I tried with require (easy with nodejs), but it doesn't work. It is impossible in geth (js console) to load an abi_1.json and store it in a variable abi_1 in the same way I easily pickle a file in python? Thank you and hope this question makes sense to the community.
As specified in the documentation[1], the geth console uses an implementation of ECMAScript in go called goja[2]. From what I know, classical JS (so no nodejs) does not have any IO functionnalities...
However, maybe you could use the 'loadScript' function available in the console + some bash.
For instance, let's say that your JSON file is located in /tmp/abi.json. All your JS operations can be stored in another file (let's say /tmp/operations.js).
You could use geth attach http://localhost:8545 --exec "var abi = $(cat /tmp/abi.json); loadScript('/tmp/operations.js')"
For example :
/tmp/file.json contains { 'test': 'Hello, world'}
geth attach http://localhost:8545 --exec "var a = $(cat /tmp/file.json); console.log(a.test)"
Would print Hello, world!
That's not a perfect solution but it could be convenient to you.
[1] https://geth.ethereum.org/docs/interface/javascript-console
[2] https://github.com/dop251/goja

Output gulp-qunit console output to file

I am running unit tests using QUnit and trying to integrate QUnit into our build automation and Continuous Integration process. For Atlassian Bamboo to parse the test output it requires the test output to be in an xml file. I can generate a console log that is in the required xml format by using the qunit-reporter-junit plugin. When Gulp-QUnit runs our test-runner.html file it outputs the console.log to the screen. My problem is that I cannot find a way to pipe this console.log output into a file.
I have tried the following approaches:
Using gulp-log-capture plugin (does nothing):
gulp.task('qunit', function() {
return gulp.src('./qunit/test-runner.html')
.pipe(logCapture.start(console,'log'))
.pipe(qunit())
.pipe(logCapture.stop('build.xml'));
});
Piping the output into a write stream (which throws an error):
gulp.task('qunit', function() {
return gulp.src('./qunit/test-runner.html')
.pipe(qunit())
.pipe(fs.createWriteStream('build.xml));
});
Using gulp-out plugin (which simply pipes the input html into the new file):
gulp.task('qunit', function() {
return gulp.src('./qunit/test-runner.html')
.pipe(qunit())
.pipe(out('build.xml');
});
The XML is right there on the screen I just need to get it into a file somehow.
It turns out that phantom js takes node-like scripts that will run on execution. I basically took the run-qunit script from the examples directory of phantom-js and adjusted it to pipe console output into a build.xml file. Example script can be found here: https://github.com/ariya/phantomjs/blob/master/examples/run-qunit.js
I simply adjusted the onConsoleMessage listener (ln48) like so:
page.onConsoleMessage = function(msg) {
if( msg.search(/xml/) > -1 ) {
fs.write('build.xml',msg);
}
console.log(msg);
};
To make this run as part of an automated build process, in Gulp I run the following task using the exec plugin.
exec = require('child_process').exec;
.
.
.
gulp.task('phantom',function() {
exec('phantomjs ./qunit/run-qunit.js ./qunit/test-runner.html');
});
Both of these adjustments successfully create a build.xml file that Atlassian Bamboo can read as part of its process.

How to check whether chrome browser is installed or not using java script?

My requirement is I need to check whether Chrome browser is insatlled on the client machine or not using Javascript. I have searched on the net not able to find the way out.
Please help in getting this done.
You can't do that with JavaScript, and even if you could, you shouldn't.
JavaScript on the client doesn't have access to the user's system, for very good reasons. (Think, servers with bad intentions.)
You can check if the browser is Chrome with the next code
if(!window.chrome){
//Chrome code
}else{
// Chrome block
}
You can't. Not with JavaScript. However, you can check whether the browser that is currently being used to view your webpage is Google Chrome or not.
<script type="text/javascript">
if(window.chrome){
document.write("Browser is Chrome");
}
else{
document.write("Please download Chrome");
}
</script>
You can't get that kind of information directly from javascript.
What you can do is use that PowerShell command in a script and save the result in a file that you'll read later using javascript.
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallLocation, Publisher, InstallDate | Format-Table -AutoSize
This will get you all the installed programs on the machine from the HKEY_LOCAL_MACHINE registry folder.
The exact path to the folder from wich the informations are retrieved is : HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
The given command will display you the application name followed by it's version, it's install location, publisher name and installation date in a PowerShell terminal.
If you want to output that list in a file simply add >FileName.txt after the command before pressing enter.
Note that by default the file will be created in the C:\Users\YourUserName\ folder so if you want the file to be created in a specific location you'll have to use the CD command to get to that specific location before executing the Get-Item-Property command.
This will get you done for the get installed programs on a machine part.
Now we can get into the check if app x is installed on the machine part.
First load the previously generated file in your js application you will use it's content to determine if an application is installed on the computer.
The faster way to get if 'chrome' is installed will be to load the file as a string and then do that basic stuff :
if (string.includes('chrome') == true) {
// chrome is installed on the machine
// you can do some more stuff
// like extracting it's path from the file content
} else {
console.log('error: chrome is not installed on this computer');
}
Needless to say that this will only work if used on the same computer from which you want to check the installed applications.
Edit: If you want a more practical file to use in javascript you can replace
Format-Table -AutoSize >FileName.txt
with :
Export-Csv -path .\FileName.txt -NoTypeInformation
this way you can split your file lines using the string.split(',') method and don't have to do some extra stuff to deal with the spaces between data.
Edit 2:
Here's a full working implementation that will let you retrieve informations from a PowerShell script directly from your javascript using NodeJs.
get_programs.ps1 (PowerShell script file) :
chcp 65001 # sets the encoding for displaying chars correctly
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallLocation | ConvertTo-Csv -NoTypeInformation
chcp 850 # restores the default encoding set this will avoid police changes due to the terminal modifications
Notice the change at the end of the command which is now:
| ConvertTo-Csv -NoTypeInformation
this allows to log data in the PowerShell terminal in the csv format which will simplify it's parsing as a string.
If you don't want to use another file to hold those few PowerShell
commands you can use this
child = spawn("powershell.exe",[`chcp 65001
Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion, InstallLocation | ConvertTo-Csv -NoTypeInformation
chcp 850`]);
as a replacement for
child = spawn("powershell.exe",["./get_programs.ps1"]);
If you choose to do this don't forget to escape the \ chars else it will not work.
app.js :
var spawn = require("child_process").spawn,child;
child = spawn("powershell.exe",["./get_programs.ps1"]); // here we start our PowerShell script "./" means that it's in the same directory as the .js file
let chromeDetails;
child.stdout.on("data", (data) => { // data event
// here we receive each outputed line in the PowerShell terminal as an Uint8Array
if (data.includes('Chrome')) { // check for the 'Chrome' string in data
chromeDetails = data.toString(); // adds data converted as string
}
});
child.stderr.on("data", (data) => { // logs errors
console.log(`Powershell Errors: ${data}`);
});
child.on("exit", () => { // exit event
console.log("Powershell Script finished");
if (chromeDetails != undefined) {
console.log(`> chrome has been detected on this computer
available informations (appName, version, installPath):
${chromeDetails}`);
} else
console.log('> chrome has not been detected on this computer');
});
child.stdin.end(); // we end the child
Expected output :
Powershell Script finished
> chrome has been detected on this computer
    available informations (appName, version, installPath):
    "Google Chrome","103.0.5060.114","C:\Program Files\Google\Chrome\Application"
If you are not on Windows you may want to take a look at Spawning .bat and .cmd files on Windows from the NodeJs documentation to get hints on how to adapt the above app.js code to work on your system.

How to read and write to a file (Javascript) in ui automation?

I want to identify few properties during my run and form a json object which I would like to write to a ".json"file and save it on the disk.
var target = UIATarget.localTarget();
var properties = new Object();
var jsonObjectToRecord = {"properties":properties}
jsonObjectToRecord.properties.name = "My App"
UIALogger.logMessage("Pretty Print TEST Log"+jsonObjectToRecord.properties.name);
var str = JSON.stringify(jsonObjectToRecord)
UIALogger.logMessage(str);
// -- CODE TO WRITE THIS JSON TO A FILE AND SAVE ON THE DISK --
I tried :
// Sample code to see if it is possible to write data
// onto some file from my automation script
function WriteToFile()
{
set fso = CreateObject("Scripting.FileSystemObject");
set s = fso.CreateTextFile("/Volumes/DEV/test.txt", True);
s.writeline("HI");
s.writeline("Bye");
s.writeline("-----------------------------");
s.Close();
}
AND
function WriteFile()
{
// Create an instance of StreamWriter to write text to a file.
sw = new StreamWriter("TestFile.txt");
// Add some text to the file.
sw.Write("This is the ");
sw.WriteLine("header for the file.");
sw.WriteLine("-------------------");
// Arbitrary objects can also be written to the file.
sw.Write("The date is: ");
sw.WriteLine(DateTime.Now);
sw.Close();
}
But still unable to read and write data to file from ui automation instruments
Possible Workaround ??
To redirect to the stdout if we can execute a terminal command from my ui automation script. So can we execute a terminal command from the script ?
Haven't Tried :
1. Assuming we can include the library that have those methods and give it a try .
Your assumptions are good, But the XCode UI Automation script is not a full JavaScript.
I don't think you can simply program a normal browser based JavaScript in the XCode UI Automation script.
set fso = CreateObject("Scripting.FileSystemObject");
Is not a JavaScript, it is VBScript which will only work in Microsoft Platforms and testing tools like QTP.
Scripting.FileSystemObject
Is an ActiveX object which only exists in Microsoft Windows
Only few JavaScript functions like basic Math, Array,...etc..Are provided by the Apple JavaScript library, so you are limited to use only the classes provided here https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/
If you want to do more scripting then Try Selenium IOS Driver http://ios-driver.github.io/ios-driver/
Hey so this is something that I was looking into for a project but never fully got around to implementing so this answer will be more of a guide of what to do than step by step copy and paste.
First you're going to need to create a bash script that writes to a file. This can be as simple as
!/bin/bash
echo $1 >> ${filename.json}
Then you call this from inside your Xcode Instruments UIAutomation tool with
var target = UIATarget.localTarget();
var host = target.host();
var result = host.performTaskWithPathArgumentsTimeout("your/script/path", ["Object description in JSON format"], 5);
Then after your automation ends you can load up the file path on your computer to look at the results.
EDIT: This will enable to write to a file line by line but the actual JSON formatting will be up to you. Looking at some examples I don't think it would be difficult to implement but obviously you'll need to give it some thought at first.

IPC on Terminal Server with C/C++ an nw.js/node.js/node-native-module (C++)?

I have a Win32-DLL (C++) which is loaded as a plugin in another application. The DLL starts a nw.js instance (ShellExecuteEx and SEE_MASK_NOCLOSEPROCESS) and ends it at DLL unloading (by the hInstance of ShellExecuteEx). I need a way to send a string (plain ansi) to the nw-process and retrieve an answer (also string). The old way was a simple http-request with the response in the body. But the environment changes during the development, the "package" app-dll-nw runs multiple times by the same user and multiple users run on the same machine (terminal server). So port listing is "impossible" (yeah random ports or singleton nw, but no).
I found different ways:
socket - port listing problem
wm_copydata/wm_... - need a custom nw-plugin with hidden window (no native nw way); no request-response-system
RPC - port listing problem
DDE - no native javascript way (found a module, which uses .net); In my old delphi days DDE was a not so simple task and it failed multiple times with no logic.
shared memory - no experience; expectations: asynchronous, trigger?, no native javascript way
shared file - no experience; expectations: asynchronous, trigger (watcher on file change) but problems with synchronization, native js way possible
named pipe - no experience; expectations: win32-api and like a chat system (in-pipe [send broadcast] and out-pipe [receive broadcast], or both in one)? If yes, I can use one name about all instances and use unique identifiers and wait for the right answer.
What is a nice and simple way to communicate like the http-way but w/o networking?
Update 1: The node module "net" is able to create a server for a named pipe. The first test, sending a string from the dll to nw, was successful.
var server = net.createServer(function(stream) {
stream.on('data', function(c) {
console.log('data:', c.toString());
});
stream.on('end', function() {
//server.close();
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
Update 2 - My Solution
With named pipe and a simplified version of https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx I found a working methode.
Server in nw.js:
var server = net.createServer(function(req) {
req.on('data', function(c) {
console.log(c.toString());
req.write('123|Hello World', 'ascii');
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
The client in C++ (no permanent connection, strange string handling, simplified error handling):
static std::string PipenameA = "\\\\.\\pipe\\MyAppDynamicGUID";
#define BUFSIZE 512
std::string SendPipeRequestA(std::string sRequest) {
DWORD dwToWrite, dwWritten, dwRead;
BOOL bSuccess;
char chBuf[BUFSIZE];
std::vector<char> buffer;
HANDLE hPipe = CreateFileA(PipenameA.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE)
return "-1|Pipe-Error 1 (connect)";
dwToWrite = (lstrlenA(sRequest.c_str())+1)*sizeof(char);
bSuccess = WriteFile(hPipe, sRequest.c_str(), dwToWrite, &dwWritten, NULL);
if (!bSuccess)
return "-1|Pipe-Error 2 (write)";
do {
bSuccess = ReadFile(hPipe, chBuf, BUFSIZE*sizeof(char), &dwRead, NULL);
if (!bSuccess && GetLastError() != ERROR_MORE_DATA)
break;
buffer.insert(buffer.end(), chBuf, chBuf + dwRead);
} while (!bSuccess);
std::string sResponse(&buffer[0]);
CloseHandle(hPipe);
return sResponse.c_str();
}
// Jonny
The answers you will get will be opinion based, be aware of that.
you can inject the data into the JS module as command line argument
for example
start nw.js MyData
and get it insinde the JS with process.argv.
now, sending the data back to the C++ executables/DLLs is a bit tricky.
if you shell-execute the process, you can have the handle to it.
you can print the data into the stdout from the JS part , and read it in the native app by getting the STDOUT handle from the process handle.
Register your nw.js app with a custom url should be an elegant way.
Such as "github://", "thunder://", "twitter://"
On windows you may have a look at:
https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
With custom url you can take simple arguments to nw.js at single-instance mode. See:
https://github.com/nwjs/nw.js/wiki/Handling-files-and-arguments#open-file-with-existing-app
If more data required maybe base64 can help, or even more by LZ-String compress method.

Categories

Resources