I can easily execute JavaScript using the built-in ScriptEngineManager. However, it gives full permission to JavaScript, which is a big problem for me.
It allows dangerous commands such as:
javax.swing.JOptionPane.showMessageDialog(null, "Hello, Server!");
java.lang.System.exit(0);
How do I limit the availability of Java functions in the Javascript Engine?
The sandbox by default blocks access to all Java classes.
NashornSandbox sandbox = NashornSandboxes.create();
sandbox.allow(File.class);
sandbox.eval("var File = Java.type('java.io.File'); File;")
delight-nashorn-sandbox
Related
I am building an Android application in Android studio with Java. I want to use Speech to text and Text to speech and some Machine Learning based python programs that I had already written.
Is it possible to do this? What is the technology stack that I need to accomplish this?
I came across various solutions like using sl4A, Jython, QPython and running the python code on the server.I have also gone through the following but I haven't found a solution yet
Execute python script from android App in Java
How to execute Python script from Java code in Android
Execute python script from android App in Java
Please explain with an example. As an example if I want to use the following python code (Speech to Text conversion using Google Speech recognition API) to run in my android app:
import speech_recognition as sr
r = sr.Recognizer()
with sr.Microphone() as src:
print("speak....")
audio = r.listen(src, 2)
print("over")
try:
print("you said: "+r.recognize_google(audio))
except:
print("cannot recognize")
What steps am I supposed to follow? What is the best way to achieve it?
Thank you in advance.
EDIT 1: Can it be achieved using azure services?
I've been using JEP as a bridge between java and python, I've never actually tried this on android apps, only webapps. (in the FAQS of the project they state that it could work)
private RunOutputModel run(RunInputModel model, String path) throws Exception {
RunOutputModel retVal = new RunOutputModel();
try (SharedInterpreter jep = new SharedInterpreter()) {
jep.eval("import sys");
jep.eval("sys.path.append('" + path + "')");
jep.eval("import master_main");
jep.set("well", model.getWell());
jep.set("startDate", model.getStartDate());
jep.set("endDate", model.getEndDate());
//other vars
jep.eval("objClass = master_main.master()");
jep.eval("x = objClass.main(path, well, startDate, endDate,/*vars*/)");
Object result1 = jep.getValue("x");
//manager result
}
} catch (Exception e) {
retVal.setStatus(e.getMessage());
Utils.log("error", e.getMessage(), path);
}
return retVal;
}
And here's python:
class master:
def __init__(self):
self.SETVARIABLES = ''
def main(self, path, well, startDate, endDate):
#stuff
By searching I've found this, they even have project examples of mixed source code app (both python and java).
I have found a link that illustrates the use of getting pwd based in the uid of the user.
I have a similar requirement in java for running a script as a different user which needs this implemetation.
The code snippet in c++ is as below:
static void su(const char* user)
{
struct passwd* pwentry=getpwnam(user);
if(!pwentry)
COUT<<"su:getpwnam:couldnot get pwd entry for user %s",user;
uid_t new_uid=pwentry->pw_uid;
struct passwd* pwentry_nmsadm=getpwnam("nmsadm");
if(!pwentry_nmsadm)
cout<<"su:getpwnam:could not get pwd for nmsadm");
gid_t new_gid=pwentry->pw_gid;
if(chdir(pwentry->pw_dir)<0)
cout<<"su:chdir";
uid_t current_uid=geteuid();
gid_t current_gid=getegid();
if(current_gid!=new_gid)
{
if(setgid(new_gid)<0)
cout<<"su:setgid";
}
if(current_uid!=new_uid)
{
if(setuid(new_uid)<0)
cout<<"su: setuid";
}
Please suggest some links that can be helpful(libraries that can be used) or solution to the above requirement in java.
Java does not provide this out-of-the-box, since it is both system dependant and would break security concepts of Java.
Some possible solutions could be:
Use a JNI wrapper to call your C++ method, so that you can do everything you need in C++
Use ssh to launch the script as a different user
Use sudo to launch the script as a different user
See also
Running UNIX commands as different user, from Java
How can I create a new process with another User Account on Windows? (Windows specific, but one answer mentions the JNI approach)
I am writing a trading program in perl with the newest Finance::InteractiveBrokers::TWS
module. I kick off a command line interface in a separate thread at the
beginning of my program but then when I try to create a tws object, my program
exits with this message:
As of Inline v0.30, use of the Inline::Config module is no longer supported or
allowed. If Inline::Config exists on your system, it can be removed. See the
Inline documentation for information on how to configure Inline. (You should
find it much more straightforward than Inline::Config :-)
I have the newest versions of Inline and Inline::Java. I looked at TWS.pm and it doesn't seem to be using Inline::Config. I set 'SHARED_JVM => 1' in the 'use Inline()' and 'Inline->bind()' calls in TWS.pm but that did not resolve the issue...
My Code:
use Finance::InteractiveBrokers::TWS;
use threads;
use threads::shared;
our $callback;
our $tws;
my $interface = UserInterface->new();
share($interface);
my $t = threads->create(sub{$interface->runUI()});
$callback= TWScallback->new();
$tws = Finance::InteractiveBrokers::TWS->new($manager); #This is where the program fails
So is Inline::Config installed on your system or not? A cursory inspection of the code is not sufficient to tell whether Perl is loading a module or not. There are too many esoteric ways (some intentional and some otherwise) to load a package or otherwise populate a namespace.
The error message in question comes from this line of code in Inline.pm:
croak M14_usage_Config() if %main::Inline::Config::;
so something in your program is populating the Inline::Config namespace. You should do what the program instructs you to do: find out where Inline/Config.pm is installed on your system (somewhere in your #INC path) and delete it.
How can I use java to get a js file located on a web server, then execute the function in the js file and get the result and use the result in java.
Can you guys give me some code snippet? Great thanks.
You can use the scripting engine built into Java:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public static void main(String[] args) throws Exception {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
Object result = engine.eval("my-java-script-code")
System.out.println("Result returned by Javascript is: " + result);
}
Here is a more elaborate example.
There's three steps to this process:
Fetch the JS file from the server.
Execute some JS function from the file.
Extract the result.
The first step is fairly simple, there are lots of HTTP libraries in Java that will do this - you effectively want to emulate the simple functionality of something like wget or curl. The exact manner in which you do this will vary depending on what format you want the JS file in for the next step, but the process to get hold of the byte stream is straightforward.
The second step will require executing the JS in a Javascript engine. Java itself cannot interpret Javascript, so you'd need to obtain an engine to run it in - Rhino is a common choice for this. Since you'd need to run this outside of Java, you'll likely have to spawn a process for execution in Rhino using ProcessBuilder. Additionally, depending on the format of the Javascript you might need to create your own "wrapper" javascript that functions like a main class in Java and calls the method in question.
Finally you need to get the result out - obviously you don't have direct access to JavaScript objects from your Java program. The easiest way is going to be for the JS program to print the result to standard out (possibly serialising as something like JSON depending on the complexity of the object), which is being streamed directly to your Java app due to the way you launched the Rhino process. This could be another job for your JS wrapper script, if any. Otherwise, if the JS function has observable side effects (creates a file/modifies a database) then you'll be able to query those directly from Java.
Job done.
I hope you realise this question is far too vague to get full answers. Asking the public to design an entire system goes beyond the point where you'll get useful, actionable responses.
There are plenty of examples on the web of how to download a file from a URL.
Suns version of the JDK and JRE includes the Mozilla Rhino scripting engine.
Assuming you have stored the contents of the javascript file in a string called 'script', you can execute scripts as follows
String result = null;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
try {
jsEngine.eval(script);
result = jsEngine.get("result")
} catch (ScriptException ex) {
ex.printStackTrace();
}
The result will be extracted from the engine and stored in the 'result' variable.
The is a tutorial on scripting in Java that might be useful.
I use Launch4j as a wrapper for my Java application under Windows 7, which, to my understanding, in essence forks an instance of javaw.exe that in turn interprets the Java code. As a result, when attempting to pin my application to the task bar, Windows instead pins javaw.exe. Without the required command line, my application will then not run.
As you can see, Windows also does not realize that Java is the host application: the application itself is described as "Java(TM) Platform SE binary".
I have tried altering the registry key HKEY_CLASSES_ROOT\Applications\javaw.exe to add the value IsHostApp. This alters the behavior by disabling pinning of my application altogether; clearly not what I want.
After reading about how Windows interprets instances of a single application (and a phenomenon discussed in this question), I became interested in embedding a Application User Model ID (AppUserModelID) into my Java application.
I believe that I can resolve this by passing a unique AppUserModelID to Windows. There is a shell32 method for this, SetCurrentProcessExplicitAppUserModelID. Following Gregory Pakosz suggestion, I implemented it in an attempt to have my application recognized as a separate instance of javaw.exe:
NativeLibrary lib;
try {
lib = NativeLibrary.getInstance("shell32");
} catch (Error e) {
Logger.out.error("Could not load Shell32 library.");
return;
}
Object[] args = { "Vendor.MyJavaApplication" };
String functionName = "SetCurrentProcessExplicitAppUserModelID";
try {
Function function = lib.getFunction(functionName);
int ret = function.invokeInt(args);
if (ret != 0) {
Logger.out.error(function.getName() + " returned error code "
+ ret + ".");
}
} catch (UnsatisfiedLinkError e) {
Logger.out.error(functionName + " was not found in "
+ lib.getFile().getName() + ".");
// Function not supported
}
This appears to have no effect, but the function returns without error. Diagnosing why is something of a mystery to me. Any suggestions?
Working implementation
The final implementation that worked is the answer to my follow-up question concerning how to pass the AppID using JNA.
I had awarded the bounty to Gregory Pakosz' brilliant answer for JNI that set me on the right track.
For reference, I believe using this technique opens the possibility of using any of the APIs discussed in this article in a Java application.
I don't have Windows 7 but here is something that might get you started:
On the Java side:
package com.stackoverflow.homework;
public class MyApplication
{
static native boolean setAppUserModelID();
static
{
System.loadLibrary("MyApplicationJNI");
setAppUserModelID();
}
}
And on the native side, in the source code of the `MyApplicationJNI.dll library:
JNIEXPORT jboolean JNICALL Java_com_stackoverflow_homework_MyApplication_setAppUserModelID(JNIEnv* env)
{
LPCWSTR id = L"com.stackoverflow.homework.MyApplication";
HRESULT hr = SetCurrentProcessExplicitAppUserModelID(id);
return hr == S_OK;
}
Your question explicitly asked for a JNI solution. However, since your application doesn't need any other native method, jna is another solution which will save you from writing native code just for the sake of forwarding to the windows api. If you decide to go jna, pay attention to the fact that SetCurrentProcessExplicitAppUserModelID() is expecting a UTF-16 string.
When it works in your sandbox, the next step is to add operating system detection in your application as SetCurrentProcessExplicitAppUserModelID() is obviously only available in Windows 7:
you may do that from the Java side by checking that System.getProperty("os.name"); returns "Windows 7".
if you build from the little JNI snippet I gave, you can enhance it by dynamically loading the shell32.dll library using LoadLibrary then getting back the SetCurrentProcessExplicitAppUserModelID function pointer using GetProcAddress. If GetProcAddress returns NULL, it means the symbol is not present in shell32 hence it's not Windows 7.
EDIT: JNA Solution.
References:
The JNI book for more JNI examples
Java Native Access (JNA)
There is a Java library providing the new Windows 7 features for Java. It's called J7Goodies by Strix Code. Applications using it can be properly pinned to the Windows 7 taskbar. You can also create your own jump lists, etc.
I have implemented access to the SetCurrentProcessExplicitAppUserModelID method using JNA and it works quite well when used as the MSDN documentation suggests. I've never used the JNA api in the way you have in your code snippet. My implementation follows the typical JNA usage instead.
First the Shell32 interface definition:
interface Shell32 extends StdCallLibrary {
int SetCurrentProcessExplicitAppUserModelID( WString appID );
}
Then using JNA to load Shell32 and call the function:
final Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
{
put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
}
};
Shell32 shell32 = (Shell32) Native.loadLibrary("shell32", Shell32.class,
WIN32API_OPTIONS);
WString wAppId = new WString( "Vendor.MyJavaApplication" );
shell32.SetCurrentProcessExplicitAppUserModelID( wAppId );
Many of the API's in the last article you mentioned make use of Windows COM which is quite difficult to use directly with JNA. I have had some success creating a custom DLL to call these API's (eg. using the SHGetPropertyStoreForWindow to set a different app ID for a submodule window) which I then use JNA to access at runtime.
Try to use JSmooth. I use always this one. In JSmooth is there an option under Skeleton by Windowed Wrapper called
Lauch java app in exe process
See on this image.
(source: andrels.com)
Also command line arguments can be passed.
I think this can be a solution for you.
Martijn
SetCurrentProcessExplicitAppUserModelID (or SetAppID()) would in fact do what you're trying to do. However, it might be easier to modify your installer to set the AppUserModel.ID property on your shortcut - quoting from the Application User Model ID document mentioned above:
In the System.AppUserModel.ID property of the application's shortcut file. A shortcut (as an IShellLink, CLSID_ShellLink, or a .lnk file) supports properties through IPropertyStore and other property-setting mechanisms used throughout the Shell. This allows the taskbar to identify the proper shortcut to pin and ensures that windows belonging to the process are appropriately associated with that taskbar button.
Note: The System.AppUserModel.ID property should be applied to a shortcut when that shortcut is created. When using the Microsoft Windows Installer (MSI) to install the application, the MsiShortcutProperty table allows the AppUserModelID to be applied to the shortcut when it is created during installation.
The latest jna-platform library now includes JNA bindings for SetCurrentProcessExplicitAppUserModelID:
https://github.com/java-native-access/jna/pull/680
I fixed mine without any ID settings.
There is an option in Launch4J if you are using it and you say you do then...
You can change the header to JNI Gui and then wrap it around the jar with the JRE.
The good thing is that it runs .exe in the process now instead on running javaw.exe with your jar. It probably does it under the hood (not sure).
Also I have noticed also that it takes around 40-50% less CPU resource which is even better!
And the pinning works fine and all that window features are enabled.
I hope it helps to someone as I spent nearly 2 days trying to solve that issue with my undecorated javafx app.