Walker
Walker

Reputation: 317

Dynamic Class Loading : Exception in thread "main" java.lang.ClassFormatError

I was trying to perform dynamic class loading from a jar file, unfortunately there was an error:

Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1347093252 in class file com/life/Life
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
    at gloria.MyClassLoader.loadClass(MyClassLoader.java:38)
    at gloria.Gloria.main(Gloria.java:9)
Java Result: 1

Here's my code:

MainClass.java

public class MainClass {

    public static void main(String[] args) {
         try{
            ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
            MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
            Class myObjectClass = classLoader.loadClass("com.life.Life");

            //create new class loader so classes can be reloaded.
            classLoader = new MyClassLoader(parentClassLoader);
            myObjectClass = classLoader.loadClass("com.life.Life");

            Life life = (Life) myObjectClass.newInstance();
            System.out.println("Message: " + life.getMessage());

        }catch(Exception e){
            e.printStackTrace();
        }
    }

}

MyClassLoader.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(ClassLoader parent) {
         super(parent);
    }

    @Override
    public Class loadClass(String name) throws ClassNotFoundException {
        if(!"com.life.Life".equals(name))
               return super.loadClass(name);

        try {
            String url = "http://192.168.1.229:8081/downloads/Life.jar";
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            InputStream input = connection.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int data = input.read();

            while(data != -1){
               buffer.write(data);
               data = input.read();
            }

            input.close();

            byte[] classData = buffer.toByteArray();

            return defineClass("com.life.Life", classData, 0, classData.length);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

Life.java

public interface Life {

    public String getMessage();

}

What Im doing right here is to instantiate an object that from a jar file and load it in runtime. What's wrong with my code? Any idea?

Upvotes: 1

Views: 525

Answers (2)

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16142

You are trying to use a JAR/ZIP file as a CLASS file; a JAR file contains class files, but isn't one.

BTW, why won't something like new UrlClassLoader("jar:http://http://192.168.1.229:8081/downloads/!/") work? This will also transparently handle loading classes that Life needs and are located in that JAR.

Upvotes: 0

Neha Gangwar
Neha Gangwar

Reputation: 678

0xCAFEBABE is the usual first 4 bytes of a Java file. Your value 1347093252 is 0x504B0304 in hex, which is the magic value for a ZIP file. As jar is also a zip file. This means that your jar can be corrupt. Try re-building the jar.

Upvotes: 2

Related Questions