Run piece of code contained in a String - java

I have a piece of Java code in a String.
String javaCode = "if(polishScreenHeight >= 200 && " +
"polishScreenHeight <= 235 && polishScreenWidth >= 220) { }";
Is it possible to convert this Java String to a Java statement and run it? Possibly using Java reflection?

As has already been suggested you can compile, save and run code on the fly using the Compiler API.
Another neat alternative would be to use beanshell. Beanshell is no longer actively developed, but I can vouch for it's reliability, I've used it successfully in multiple production projects.

Use BeanShell. There's a page on how to use it from Java.

Beanshell (as Boris suggested) is a way to "execute" java source code. But it looks like, you want to "execute" fragments that can interact with the compiled classes. Your example contains variabe names.
Reflection will definitly not help, because reflection targets classes ("classfiles").
You could try to define a complete class ("valid java source file"), compile it and load it (url classloader). Then you should be able to use the methods from that "live generated class". But once a class is loaded, you can't get rid of it (unload), so this will work only once (AFAIK).

As far as I know there is no simple way to do this.
However, in Java 6 onwards, you can compile source code for complete classes using javax.tools.Compiler. The compiled classes can then be loaded and executed. But I don't think this will achieve what you want.

Another way would be to execute your code as Groovy code, see this for an example.

you can use this code to run method from using this code
new Statement(Object target, String methodName, Object[] arguments).execute();
import java.beans.Statement;
public class HelloWorld {
public void method_name(String name) {
System.out.println(name);
}
public static void main(String[] args) throws Exception {
HelloWorld h = new HelloWorld();
new Statement(h, "method_name", new Object[]{"Hello world"}).execute();
}
}

Please reevaluate your design and this should be your last alternative.
You should validate the sanity of the String which will be executed to avoid future injection attack.
Now If you can have the String as JavaScript then below code should help,
public class EvalScript {
public static void main(String[] args) throws Exception {
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
// below JS function is executed.
/*
* student object value will be provided by the program as the JSON String.
function checkStudentElgibility(student){
if(student.age >= 10 && student.currentGrade >= 5){
return true;
}
}
// student object value will be provided by the program as the JSON String
checkStudentElgibility(student);
*/
String studentJsonString = "{\n" +
" \"age\" : 10,\n" +
" \"currentGrade\" : 5\n" +
"}";
String javaScriptFunctionString = "function checkStudentElgibility(student){\n" +
" if(student.age >= 10 && student.currentGrade >= 5){\n" +
" return true;\n" +
" }\n" +
"}\n" +
"checkStudentElgibility(student);";
StringBuilder javaScriptString = new StringBuilder();
javaScriptString.append("student=");
javaScriptString.append(studentJsonString);
javaScriptString.append("\n");
javaScriptString.append(javaScriptFunctionString);
Object object = engine.eval(javaScriptString.toString());
System.out.println(object);
// You can also pass the object as follows,
// evaluate JavaScript code that defines an object with one method
engine.eval("var obj = new Object()");
engine.eval("obj.hello = function(name) { print('Hello, ' + name)
}");
// expose object defined in the script to the Java application
Object obj = engine.get("obj");
// create an Invocable object by casting the script engine object
Invocable inv = (Invocable) engine;
// invoke the method named "hello" on the object defined in the
// in js Object with "Script Method" as parameter
inv.invokeMethod(obj, "hello", "Script Method!");
// You can also use Java Objects as Java script object and you can also pass Objects as reference inside Java script function
String jsString = " var obj = new Object()\n" +
" var ArrayList = Java.type(\"java.util.ArrayList\");\n" +
" var customSizeArrayList = new ArrayList(16);\n" +
" obj.hello = function(name) { \n" +
" customSizeArrayList(name); \n" +
" print('Hello, ' + name) \n" +
" }";
}
}
Reference :
https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/javascript.html#A1147187

Try the JavaCompiler API.
Someone else answered this way better than I could, though:
Convert String to Code
Be careful before actually using something like this...

It is not Java, but as pgras has already suggested you could use GrooyScript like so :
Binding binding = new Binding();
GroovyShell shell = new GroovyShell(binding);
String[] strings = new String[]{"World", "Groovy"};
shell.setVariable("args", strings);
String script = "return \"Hello \" + args[1]";
String value = (String) shell.evaluate(script);
System.out.println(value); // Hello Groovy

Related

How can java object from java code be passed to R script?

i'm curious is it possible to path java object (in any type (java/class/jar)) to REngine? till now i'm successfully executing an operation from java to R or vice versa. for example: i have my custom jar files which i'm using in RStudio, i wish to have same opportunity from java code as well.
above code is from RStudio
bellow code is from java
String javaVector="c(1,2,3,4,5)";
Rengine rengine = new Rengine(new String[]{"-no-save"}, false, null);
rengine.eval("rVector <-"+javaVector);
rengine.eval("meanVal=mean(rVector)");
double mean = rengine.eval("meanVal").asDouble();
REXP rexp = rengine.eval("meanVal");
System.out.println("Mean of given vector is <-"+mean);
rengine.eval(String.format("greeting <- '%s'", "Hello R World"));
REXP result = rengine.eval("greeting");
System.out.println("Greeting from R: "+result.asString());
i will answer my question. if someone is interested in answer. so to path java object from java code to R script you can do next: first pick the object you want to work with, for example :
public class RAccess{
static public Object getObject(String id){
return test;
}
static TestClass test = new TestClass();
}
public class TestClass{
String message;
public void setMessage(String value){
message = value;
}
}
after evaluate R script exactly like you do it in R console or RStudio, just put it in curly braces.
REXP x = re.eval(rCode3);
System.out.println(RAccess.test.message);
static String rCode3 =
"{ \n" +
"library(rJava) \n" +
".jinit() \n" +
"obj <- .jcall(\"jriTest/RAccess\", \"Ljava/lang/Object;\", \"getObject\", \"id\") \n" +
".jcall(obj, \"V\", \"setMessage\", \"hello from R\") \n" +
"}";
jriTest is a package name.

Storing objects in a database java

So I'm working on a program to interface with a file based database. Mostly I'm trying to figure out how to work with it so that I can make objects and store their information in the database so that I can pull the data later.
IE Object Taylor
Name = Taylor
Age = 20
School = Whatever
So that I can get back on and call that information up when queried.
This is an example of an object I want to store. I may be doing this part wrong.
package com.catalyse.db;
public class Taylor implements java.io.Serializable
{
public String name = "Taylor M May";
public int age = 20;
public String school = "UC Boulder";
}
The DB structure I'm using is based on RandomAccessFile and I didn't make it, I'm just trying to figure out how to implement it.
package com.catalyse.db;
import java.util.*;
import java.util.Scanner;
/**
* Simple test class for the RecordsFile example. To run the test,
* set you CLASSPATH and then type "java hamner.dbtest.TestRecords"
*/
public class Run {
static void log(String s) {
System.out.println(s);
}
private static String name()
{
Scanner name = new Scanner(System.in);
String name1 = name.next();
return name1;
}
public static void main (String[] args) throws Exception {
System.out.println(new Date());
Scanner SC = new Scanner(System.in);
log("What would you like to name the database?");
String filename = SC.next();
log("creating records file...");
RecordsFile recordsFile = new RecordsFile(filename+".records", 64);
log("adding a record...");
RecordWriter rw = new RecordWriter("foo.username");
rw.writeObject(new Taylor());
recordsFile.insertRecord(rw);
log("reading record...");
RecordReader rr = recordsFile.readRecord("foo.username");
Taylor name = (Taylor)rr.readObject();
System.out.println("\tlast access was at: " + name.toString());
log("test completed.");
}
}
And here is what I get back from it,
Wed Nov 20 11:56:04 MST 2013
What would you like to name the database?
save3
creating records file...
adding a record...
reading record...
last access was at: com.catalyse.db.Taylor#50aed564
test completed.
My problem is that I want it to return information about the class, not just its name and location in the DB.
You need to override the toString method.
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Name: ");
sb.append(this.name);
//rest of fields
return sb.toString();
}
As a matter of clarity, you are not returning its location in the database. You are getting back the object hashValue + the class name.
At this point
Taylor name = (Taylor)rr.readObject();
You can access whatever information you like in the object, e.g.
Taylor name = (Taylor)rr.readObject();
System.out.println(name.age + ", " + name.name + ", " + name.school);
Alternatively, just add a
public String toString()
{
return name + ", " + age + ", " + school;
}
method in Taylor and then output it like so
Taylor name = (Taylor)rr.readObject();
System.out.println(name);
Now, concerning...
System.out.println("\tlast access was at: " + name.toString());
name.toString() isn't really required. If you append an object to a String then it automatically calls that objects toString() method to get a value.
Lastly, I'd like to note that generally we don't access object members like name, school and age by just accessing them. We generally make them private members then add methods to get and set them, so that we control and can track how they are manipulated.

Validation of java object using javascript

I have following task for my project:
I need to validate a java object, based on rules in a script (for example javascript).
Why in javascript?
Because in javascript I can be flexible and create rules as I want (e.g. validating a combination of fields like validate(tax,recipient))
Now here is what I have:
1) I have validation rules defined in a javascript file, Rules.js
function checkPrice(price){
if(price < 0){
return false;
}
}
2) I have a plain Java Object (Invoice). And it must stay plain!
public class Invoice implements Serializable {
private String details;
private String tax;
private String recipient;
private double price;
//getter and setter
}
3) And I have a ValidatorObject. This can be a java or javascript object. Depending on your suggestion.
This ValidatorObject has a method validate, which has the Javascript Rules File (see Point 1) and the Java Object, Invoice, (see Point 2) as parameters.
validate(Rules.js, Invoice i){
//here it must take the Rules.js and use the rules inside to validate the Invoice i
}
So my question would be:
Are there any frameworks that I can use to validate a Java Object based on rules defined in a javascript file? Or any tutorials, videos or suggestions?
Or how can I read a javascript file into a java object? Are there any getters or setters for javascript?
Anything would be nice!
Regards,
Dave
Here is how to embed a ScripEngine into Java Application:
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public static void main( String[] args )
throws
ScriptException, IOException
{
final String run;
if( args.length > 0 )
{
run = args[0];
if( run.contains( "=" ))
{
usage();
}
}
else
{
run = "run.js";
}
File script = new File( run );
if( script.canRead())
{
ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType( "text/javascript" );
Bindings bindings = engine.getBindings( ScriptContext.GLOBAL_SCOPE );
bindings.put( "controller", new Controller());
for( int i = 1; i < args.length; ++i )
{
String[] varVal = args[i].split( "=" );
if( varVal.length == 2 )
{
bindings.put( varVal[0], varVal[1] );
}
else
{
usage();
}
}
info( "Loading and executing: " + script );
engine.put( ScriptEngine.FILENAME, script.toString());
engine.eval( new FileReader( script ));
}
else
{
System.err.println( "Can't read automation script file: " + script );
usage();
}
}
In this case the Controller Java class exposes some public methods to JavaScript to use the flexibility of the interpreted code coupled to the robustness of compiled Java code.
I solved it using Rhino! where I can read and manipulate my javascript file...
https://developer.mozilla.org/en-US/docs/Rhino

executing javascript code inside Android "java" application

I'm working on an Android app "native written in java"
and I'm getting a response from a server the response is a javascript function
I need to use this function to do some calculations inside my native java code.
any ideas how to do so.
sample response :
function logic_1(surveyString, responseValuesString) {
var survey = eval(surveyString);
var responseValues = eval(responseValuesString);
var target = new Object();
if (isChosen(128133225, responseValues)) {
target.id = 2;
}
if (! target.id) {
target.id = 2;
}
return target;
}
I've previously used Rhino successfully to execute JavaScript code on Android:
http://www.mozilla.org/rhino/
Here's an example of how to return values from a complex type:
String strFunction =
"function add(x,y){ " +
"return { " +
"id:x+y " +
"}; " +
"}";
Context context = Context.enter();
ScriptableObject scope = context.initStandardObjects();
context.evaluateString(scope, strFunction, "test", 1, null);
Function functionAdd = (Function)scope.get("add");
NativeObject untypedResult = (NativeObject)functionAdd.call(context, scope, scope, new Object[] { 1, 2 });
double id = (Double)untypedResult.get("id", untypedResult);
The important part is the last two lines, where we call the JavaScript function, treat the result as a NativeObject, and then retrieve the value of the 'id' property from that object.
Maybe you just need to use a JavaScript auto executing function like this:
(function(x, y){
var result;
result = x + y; // do some calculations
return result;
})(1 , 2); // you can set your parameters from Java
and 1, 2 are just two parameters from Java

Whats the best pratice to show multiple placemarks with photos inside of the ballons?

I have a project as follows: Several photos are taken from a mobile, the photos are saved in a web system, which in turn displays the photos on google earth that is inside it. I've read many articles but all of them were using fetchKml, one good article that i've read was using php, but using fetchKml. I dont know if its possible using parseKml instead. Anyway, I'm not sure how to do this with the kml, so it looks tike this:
My Class KMLGenerator()
public static String getKMLFromObra (List<Obra> obraFotos) {
StringBuffer sb = new StringBuffer();
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<kml xmlns='http://www.opengis.net/kml/2.2' " +
"xmlns:gx='http://www.google.com/kml/ext/2.2' " +
"xmlns:kml='http://www.opengis.net/kml/2.2' " +
"xmlns:atom='http://www.w3.org/2005/Atom'> ");
if (obraFotos != null && obraFotos.size() > 0) {
for (Obra o : obraFotos) {
for (Local local : o.getLocais()) {
sb.append("<Document>");
sb.append("<name>" + local.getName() + "</name>");
sb.append("<Style id='defaultStyles'>");
sb.append("<IconStyle>");
sb.append("<scale>1.1</scale>");
sb.append("<Icon>");
sb.append("<href>" + "http://localhost:8080/ConstruMobilFoto/lib/img/fotoIcon.png" + "</href>");
sb.append("</Icon>");
sb.append("</IconStyle>");
sb.append("</Style>");
sb.append("<Placemark>");
sb.append("<name>" + "Foto" + "</name>");
sb.append("<styleUrl>" + "#defaultStyles"+ "</styleUrl>");
sb.append("<altitudeMode>" + "relativeToGround" + "</altitudeMode>");
sb.append("<Point>");
sb.append("<altitudeMode>relativeToGround</altitudeMode>");
sb.append("<coordinates>" + local.getLongitude() + "," + local.getLatitude() + "," + 50</coordinates>");
sb.append("</Point>");
sb.append("<Link>");
sb.append("<href>" + local.getFotos() + "</href>");
sb.append("</Link>");
sb.append("</Placemark>");
sb.append("</Document>");
sb.append("</kml>");
return sb.toString();
}
}
}
return null;
}
I have a dwr function in my jsp that invokes this method, got its String results and make the parse like this:
Class PainelEarth()
#SuppressWarnings("static-access")
public String geraFotosObra (int idObra) throws Exception {
try {
List<Obra> obraFotos = obraBusiness.getObraLatLong(new Obra(idObra));
return new KMLGenerator().getKMLFromObra(obraFotos);
} catch (Exception e) {
log.error(e.getLocalizedMessage(), e);
return null;
}
}
and in my jsp page
function initCB(instance) {
// other codes
showPics(ge);
}
function showPics(ge) {
PainelEarthAjax.geraFotosObra({
callback : function(kmlString) {
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}
});
return null;
}
Any help will be welcome!!
In your code if you look at the signature of the method geraFotosObra you can see it takes a single int parameter idObra.
public String geraFotosObra (int idObra) throws Exception { ...
Yet when you call the method in your jsp you are passing an an object literal containing a callback function.
PainelEarthAjax.geraFotosObra({
callback : function(kmlString) { ...
As it is I don't see how the kml is generated, unless perhaps geraFotosObra is an overloaded method? Also even if it was generated, as is, I don't see how the callback function that you pass in place of an id is ever called - why for example would kmlString be the result of the call to geraFotosObra?
// How is this called, what sets kmlString!?
callback : function(kmlString) {
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}
All in all the code you posted is a wee bit confusing, so sorry if I have missed something...I think you have possibly copy and pasted some code from a fetchKml example and the asynchronous callbacks used with that method have confused you slightly.
Anyhow, based on what you have posted, you should be passing an int id to the geraFotosObra method, getting the string result and then parsing it in the plug-in.
Something like the following makes sense. Replace the showPics function with the following.
function showPics(ge) {
var kmlString = PainelEarthAjax.geraFotosObra(1); // or something?
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}

Categories

Resources