title: Android: Load custom classes at runtime from jar file placed in the assets folder
body: <p>I am developing an Android app which reads excel file from assets. I was using POI-3.9 library for reading .xls files and was working properly. Then I had to read .xlsx files as well, so I added other jar files like poi-ooxml-schemas-3.9.jar, poi-ooxml-3.9.jar, log4j.jar ... etc. But when I tried to build the app, the eclipse freezed and crashed. Then I tried to build the project using command line and it reveals the error of limitation of dex file that it can have maximum of 64K methods and my project was exceeding 66K. Then I tried to remove some jar files to find out which file is having such large number of methods and found that it was poi-ooxml-schemas-3.9.jar. So I planned to place the poi-ooxml-schemas-3.9.jar file in assets folder and load the jar using DexClassLoader api. But it gives ClassNotFoundException everytime even though while debugging I could saw some of the class name entries in the DexClassLoader instance. I don't know where I am going wrong. Is my jar file in wrong format to be read by DexClassLoader or something else? Here is my sample code I am using:</p>
  
  <pre><code>    public class MainActivity extends Activity {
  
      @SuppressLint("NewApi")
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          File dexInternalStoragePath = new File(getDir("dex", Context.MODE_PRIVATE), "dexx.jar");
          BufferedInputStream bis = null;
          OutputStream dexWriter = null;
  
          final int BUF_SIZE = 8 * 1024;
          try {
              bis = new BufferedInputStream(getAssets().open("dexx.jar"));
              dexWriter = new BufferedOutputStream(
                      new FileOutputStream(dexInternalStoragePath));
              byte[] buf = new byte[BUF_SIZE];
              int len;
              while((len = bis.read(buf, 0, BUF_SIZE)) &gt; 0) {
                  dexWriter.write(buf, 0, len);
              }
              dexWriter.close();
              bis.close();
  
  
              // Internal storage where the DexClassLoader writes the optimized dex file to
              final File optimizedDexOutputPath = getDir("dex", Context.MODE_PRIVATE);
  
              DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
                                                      optimizedDexOutputPath.getAbsolutePath(),
                                                      null,
                                                      getClassLoader());
  
              Class myLibraryClazz = cl.loadClass("org.apache.poi.openxml4j.opc.OPCPackage");
  
  
          } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
  
      }
  }
  </code></pre>