我的项目的目标是从移动设备执行用户输入的Java代码。
到目前为止,我已经能够从EditText中获取用户输入的代码,并将其插入到设备的数据/文件夹中的.java文件中。
我现在坚持将.java文件从设备中编译成.class,然后我可以将.class转换为.dex并执行包含用户代码的方法。
这是我用来创建.java文件的代码。对于此示例,我创建了一个表示用户输入的字符串,但在应用程序中,它将从EditText框中获取:
writeJavaFile("public class UserClass{public void userMethod(){\n\n\n\n}}");
insertUserCode("System.out.println(\"This is a print\")");
private void insertUserCode(String userData){
try{
File file = new File(getFilesDir(),"TestClass.java");
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder text = new StringBuilder();
String line;
int counter = 0;
while((line = br.readLine()) != null) {
if(counter == 2){
text.append(userData);
}else{
text.append(line);
}
counter++;
}
br.close();
writeJavaFile(text.toString());
}catch(Exception e){
e.printStackTrace();
}
}
private void writeJavaFile(String stringToInsert) {
try{
FileOutputStream fOut = openFileOutput("TestClass.java", MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write(stringToInsert);
osw.flush();
osw.close();
}catch(Exception e){
e.printStackTrace();
}
}
答案 0 :(得分:3)
无法在移动设备/ Android设备中编译java文件,因为移动设备没有用于将.java文件转换为.class文件的JDK。
另外,android没有JDK它有DVM(Dalvik虚拟机)或ART(Android运行时),负责将.dex文件转换为机器相关代码。
要实现这一点,您必须在应用程序中实现JDK,并且由于JDK / JVM是依赖于平台的,因此您必须编写自己的JDK代码才能在您的应用程序中工作。
我建议您查看 JRE (Java运行时环境)和 JDK (Java开发工具包)。
答案 1 :(得分:1)
我使用groovy
。了解更多详情。您可以动态运行。
import groovy.lang.GroovyShell;
import groovy.lang.Script;
public class Test {
public static void main(String[] args) throws Exception{
String input = "public int calculate() { " +
" return 5 + 10;" +
"}";
Script groovyShell = new GroovyShell().parse(input);
int result = (Integer)groovyShell.invokeMethod("calculate", null);
System.out.println("Result : " + result);
}
}
<强>更新强>
以下是我的Web应用程序的示例动态输入。 用户从UI输入此脚本/ java代码。我们有经常变化的计算。这就是我们思考动态计算方式的原因。
我的程序是动态运行的
以下script/java code
来自UI输入..
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import com.java.groovy.DateUtils;
import com.java.groovy.ParamConstant;
import com.java.groovy.CalcConstant;
import com.java.groovy.CalcResult;
public Map<String, BigDecimal> calculate(Map<Object, Object> map) {
def script = new GroovyScriptEngine('resources/').with {loadScriptByName('CalculatorUtils.groovy')};
this.metaClass.mixin script;
BigDecimal oldPremium = map.get(ParamConstant.OLD_PREMIUM);
Date startDate = map.get(ParamConstant.START_DATE);
Date endDate = map.get(ParamConstant.END_DATE);
Date endorsementDate = map.get(ParamConstant.ENDORSEMENT_DATE);
BigDecimal actRate = map.get(ParamConstant.ACTUAL_RATE);
int year = DateUtils.getPeriodOfYears(startDate, endDate);
int term = 0;
if (year >= 1) {
term = DateUtils.getPeriodOfDays(startDate, endDate);
} else {
term = DateUtils.getPeriodOfDays(startDate, endDate) + 1;
}
int passedDays = DateUtils.getPeriodOfDays(startDate, endorsementDate) + 1;
int restDays = DateUtils.getPeriodOfDays(endorsementDate, endDate) + 1;
Map<String, BigDecimal> result = new HashMap<String, BigDecimal>();
// Calculate Short Period Rate
BigDecimal shortPeriodRate = new BigDecimal(calcMotorShortPeriodRate(startDate, endDate));
BigDecimal newPremium = actRate.multiply(shortPeriodRate);
// Pro-Rata Rate with old vehicle
BigDecimal oldVehProRataRate = calcMotorProRataRate(passedDays, oldPremium.doubleValue(), term);
// Pro-Rata Rate with new vehicle
BigDecimal newVehProRataRate = calcMotorProRataRate(restDays, newPremium.doubleValue(), term);
BigDecimal balanceAmountWithOldPremium = (oldPremium.subtract(oldVehProRataRate));
BigDecimal endorseAmount = (newVehProRataRate.subtract(balanceAmountWithOldPremium));
newPremium = newPremium.setScale(CalcConstant.RESULT_DECIMAL_LIMIT, RoundingMode.HALF_UP);
result.put(CalcResult.PREMIUM, newPremium);
endorseAmount = endorseAmount.setScale(CalcConstant.RESULT_DECIMAL_LIMIT, RoundingMode.HALF_UP);
result.put(CalcResult.ENDORSEMENT_AMOUNT, endorseAmount);
return result;
}