2

The goal of my project is to execute user entered Java code from the mobile device.

So far I have been able to take in the code that the user types in from the EditText and insert it into a .java file in the data/ folder of the device.

I now stuck on compiling that .java file from within the device into a .class so that I can then turn the .class into a .dex and execute the method containing the user's code.

Here is the code to which i use to create the .java file. For this example, I have created a string to represent a user input, but in the application it would be taken from an EditText box:

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();
    }
}
4
  • 1
    have u considered using a server to achieve this? e.g. sending code to a server compile it and send back .class file to the device Commented Jun 2, 2015 at 9:42
  • Sorry @nafas I would prefer it to be compiled in the device. Commented Jun 2, 2015 at 9:47
  • 2
    I don't think that's possible, but if anyone has ideas, I'm all ears (well, eyes)... Commented Jun 2, 2015 at 9:48
  • You can do it in Java , not sure about the device though docs.oracle.com/javase/8/docs/api/javax/tools/JavaCompiler.html Found this , it may be useful stackoverflow.com/questions/9731446/… Commented Jun 2, 2015 at 10:36

2 Answers 2

2

Compiling a java file in a mobile/android device is not possible because Mobile device don't have a JDK for converting .java file to .class file.

also,android has no JDK it has DVM(Dalvik Virtual Machine) or ART(Android Runtime) which is responsible to convert .dex file to machine dependent code.

To achieve this you have to implement a JDK in your application and since JDK/JVM is platform dependent your have to write your own code for JDK to work in your application.

I want to suggest you to take a look at JRE (Java Runtime environment) and JDK (Java Development Kit).

Sign up to request clarification or add additional context in comments.

2 Comments

'JVM for converting .java file to .class file' I think you meant JDK
yes, JDK is used to convert .java file to .class file.
1

I use groovy. Learn more details. You can run dynamically.

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);
    }
}

Update

Here is example dynamic input from my web application. The user input this script/java code from UI. We was have calculation which was change frequently. That's why we was think dynamic calculation way.

My program is run dynamically

The following script/java code come form UI input..

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;
    }

1 Comment

Advance! We don't need to re-deploy the application :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.