How to install ECJ library on Android environment ?

1. Installation of Eclispe and Android SDK

First of all, to make the development of Android app easier, you have to install the Eclipse framework. In this environment, you will have to install the Android SDK to get all the tools. This two first steps are explained here :
- In French
- In English
Then, you have to download the ECJ library here
You can find the official ECJ manual here

2. Create a new Android Project

When the two first steps are done, we will create a new Android project with eclipse.

 - File -> new -> Android application project



- Give a name at your project and let the default configurations.
- In your workspace, your new project should be as shown below :




3. Add ECJ library in your project

- Add in the libs folder the ecj.jar file.

Even if ecj.jar is in the libs folder, it shouldn't appear in your workspace. You have to add it in your build path.

- Right click on the project name -> build path -> configure build path...
- Libraries tab -> add external JARs... and select "ecj.jar" in the "libs" folder
- Go on the Order and Export tab -> select "ecj.jar" 





Now, the ECJ library can be used in your Android app, but this library uses some external files including a configuration file. From your Android app point of view, this file is an external file. It's not obvious to include in your app. We will see how to collect the information of this configuration file. First of all you have to create it :

- Right click on src -> new -> package
- Name it "assets" 



- Right click on this new package -> new -> File
- Name the new file "config_ecj.params" for exemple



You can now edit your configuration file as usual.

4. Collect configuration data

Now, to get the all data in “config_ecj.params”, we have to create an InputStream.
Add these lines in your code :

InputStream configStream = null;
try {
  Context mContext = this;
  configStream = mContext.getAssets().open("config_ecj.params");
}
catch (IOException e) {
  e.printStackTrace();
}

If your configuration file is named “config_ecj.params”, located in the assets package and “this” correspond to the current context of your application, this code shouldn't cause any problem. It only remains to transfer the InputStream “configStream” at the ParameterDatabase who's in charge of initializing ECJ. Here is how to initialize the ParameterDatabase :

ParameterDatabase paramDB = null;
try {
  paramDB = new ParameterDatabase(configStream);
}
catch (IOException e) {
  e.printStackTrace();
}

Now, you could run your evolutionary algorithm with the code below (more details are given in the ECJ manual, page 44)

EvolutionState evaluatedState = Evolve.initialize(paramDB, 0);
evaluatedState.startFresh();
int result = EvolutionState.R_NOTDONE;
while( result == EvolutionState.R_NOTDONE )
  result = evaluatedState.evolve();
 

If you want to be convinced that your configurations are in the InputStream, you can add this code who's in charge of printing the data in the InputStream on logCat console :

String out = "";
try{
  InputStreamReader configStreamReader = new InputStreamReader(configStream);
  BufferedReader br = new BufferedReader(configStreamReader);
  String ligne = "";
  while ( (ligne=br.readLine()) != null) {
    out += ligne + "\n";
  }
  br.close();
} 
catch (Exception e) {
  e.printStackTrace();
}
System.out.println("Out => " + out);



6. Write in a File with Android

However, ECJ may need a real File to run, and not an InputStream. For example, to initialize a population.

In this part we'll see how to write a file. As in the previous example you'll need a package named “assets”.
Create a file in your workspace named “config_ecj_in.in” (for an initialization file, by example). After, you'll need the context of you application :

Context mContext = this; 

Then, you have to load your file on your smartphone :

File file = mContext.getFileStreamPath("config_ecj_in.in"); 

Finaly, you can write into your file thanks to a FileWrite and a BufferedWriter :

FileWriter fileWriter = null;
try {
  fileWriter = new FileWriter(file);
}
catch (IOException e1) {
  e1.printStackTrace();
}
BufferedWriter output = new BufferedWriter(fileWriter);
try {
  output.write("Hello World ! ");
}
output.flush();
catch (Exception e) {
  Toast.makeText(mContext, "Settings not saved", Toast.LENGTH_SHORT).show();
}
finally {
  try {
    output.close();
    fileWriter.close();
  }
  catch (IOException e) {
    Toast.makeText(mContext, "Settings not saved", Toast.LENGTH_SHORT).show();
  }
}

As you can understand, this code write the text “Hello World” into the file “config_ecj_in.in”.

7. Use a file in an another one

Now, you can use this file as in the previous example.

But, as we said before, ECJ may need a file. Or more precisely, the path of this file.
For a population initialization, you give the path of the initialization file to the configuration file.
This path is the following one:
/data/data/name_of_your_current_project/files/config_ecj_in.in.

If you want to initialize your population “config_ecj_in.in” from the configuration file “mainConfigFile.params”, add this line in “mainConfigFile.params”:

pop.file = /data/data/name_of_your_current_project/files/config_ecj_in.in

Now, if you load “mainConfigFile.params” as show in this example you will also initialize you popullation with “config_ecj_in.in”.
Simple, isn't it ?
Here is the end of our tutorial. Good luck !

Any questions or suggestions ? Contact us !

written by Ancelin Arnaud, Aliénor Diaz, Olivier Fauvel-Jaeger, Frédéric Guégan in 2013/06