title: android load class from jar file
body: <p>I have written a Java Classloader to load classes from a <code>.jar</code> file.</p>
  
  <p>However when I load a Class I get a <code>ClassNotFoundException</code>.  The <code>.jar</code> file is located in folder assets. Before the operation I copied the <code>.jar</code> file in another directory. </p>
  
  <p>Why does it happen and how can I load class from jar file?</p>
  
  <pre><code>@Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  
      this.requestWindowFeature(Window.FEATURE_NO_TITLE);
      setContentView(R.layout.main);
      try {
          final File dexInternalStoragePath = new File(getDir("lib", Context.MODE_PRIVATE), SECONDARY_DEX_NAME);
          (new PrepareDexTask()).execute(dexInternalStoragePath);
          if (dexInternalStoragePath.exists()) {
              final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
  
              DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
                      optimizedDexOutputPath.getAbsolutePath(), null, getClassLoader());
              try {
                  JarFile jarFile = new JarFile(dexInternalStoragePath.getAbsolutePath());
                  Enumeration&lt;?&gt; e = jarFile.entries();
  
                  URL[] urls = { new URL("jar:file:" + dexInternalStoragePath.getAbsolutePath() + "!/") };
                  URLClassLoader cl1 = URLClassLoader.newInstance(urls);
  
                  while (e.hasMoreElements()) {
                      JarEntry je = (JarEntry) e.nextElement();
                      if (je.isDirectory() || !je.getName().endsWith(".class")) {
                          continue;
                      }
                      String className = je.getName().substring(0, je.getName().length() - 6);
                      className = className.replace('/', '.');
                      if (className.equals("com.common.lvl.LibraryProvider")) {
                          LibraryInterface lib = (LibraryInterface) Class.forName(className, true,  cl1).newInstance();
                          //Class&lt;?&gt; libProviderClazz = cl1.loadClass(className);
                          //LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
                          lib.CheckLVL(this, "hello");
                      }
                  }
  
                  // Class&lt;?&gt; libProviderClazz =
                  // cl.loadClass("com.common.lvl.LibraryProvider");
                  // LibraryInterface lib = (LibraryInterface)
                  // libProviderClazz.newInstance();
                  // lib.CheckLVL(this, "hello");
              } catch (Exception ex) {
                  Logger.Instance().WriteLine(this, ex.getMessage());
              }
          }
      } catch (Exception ex) {
  
      }
  }
  
  private boolean prepareDex(File dexInternalStoragePath) {
      BufferedInputStream bis = null;
      OutputStream dexWriter = null;
  
      try {
          bis = new BufferedInputStream(getAssets().open(SECONDARY_DEX_NAME));
          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();
          return true;
      } catch (IOException e) {
          if (dexWriter != null) {
              try {
                  dexWriter.close();
              } catch (IOException ioe) {
                  ioe.printStackTrace();
              }
          }
          if (bis != null) {
              try {
                  bis.close();
              } catch (IOException ioe) {
                  ioe.printStackTrace();
              }
          }
          return false;
      }
  }
  
  private class PrepareDexTask extends AsyncTask&lt;File, Void, Boolean&gt; {
  
      @Override
      protected void onCancelled() {
          super.onCancelled();
      }
  
      @Override
      protected void onPostExecute(Boolean result) {
          super.onPostExecute(result);
      }
  
      @Override
      protected Boolean doInBackground(File... dexInternalStoragePaths) {
          prepareDex(dexInternalStoragePaths[0]);
          return null;
      }
  }
  </code></pre>