Avatar billede kernelx Juniormester
11. juni 2009 - 12:14 Der er 10 kommentarer og
1 løsning

fra java-class-byte-array til et java-Object

Hi,

jeg har et byte[]-array som indeholder en java.class-fil.
Er det muligt flexibelt at loade denne class-byte[]-array og for en Object-instance af denne klasse - og invoke lidt rundt i den?

Step 1 (Test.java):
+++++++++++++++++++
package test;

public class Test {
  public void sayHello() {
    System.out.println( "hello" );
  }
}
+++++++++++++++++++

Step 2 (java.class)

Step 3 (read file into byte[]-array)

Step 4:
++++++++++++++++++
public Object loadClass( byte[] javaClass ) {
  Object classObj =
      Class.loadClassFromByteArray( javaClass ).getInstance();
  return classObj;
}
++++++++++++++++++

Hvordan skal loadClass se ud, når den skal få en java-byte-array (som indeholder en java.class-fil) til at virke?


med venlig hilsen
KernelX
Avatar billede mcb2001 Nybegynder
11. juni 2009 - 12:35 #1
hvis ud allerede kender lokationen af filen (hvor du læser bytes fra) hvorfor så ikke få java til at læse et nyt object ud fra denne fil? Det skulle være ret lige til...
Avatar billede mcb2001 Nybegynder
11. juni 2009 - 12:36 #2
Avatar billede kernelx Juniormester
11. juni 2009 - 14:00 #3
Det skal være en slags server, hvor der kan tilføjes modules.
En module er noget i stil af en java-class med annotations.

Denne server skal få en api, hvor man kan sende nye java-module-classes, og på den anden side fjerner dem, som man ikke længere har brug for.

Så der er ingen scp-, ftp-, eller lignene access, hvor jeg kan putte java-class-filerne hen. Der er kun en slags servlet, som modtager en TCP-request, som bl.a. indeholder en byte-array med java-classes.

OK, det burde være muligt at putte byte[]-data ind i en fil på server-siden og så får fat i dem med Class.forName()?!?
Avatar billede mcb2001 Nybegynder
11. juni 2009 - 14:13 #4
hvad med at kigge på Serialization og bruge dette - det er Javas egen måde at løse lige akurat denne funktionalitet på...
Avatar billede arne_v Ekspert
11. juni 2009 - 15:15 #5
Du skal bare lave din egen lille classloader.

Demo:

package june;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

public class BytesToClass {
    private static byte[] load(String fnm) throws IOException {
        File f = new File(fnm);
        byte[] b = new byte[(int)f.length()];
        InputStream is = new FileInputStream(f);
        int ix = 0;
        while(ix < b.length) {
            ix += is.read(b, ix, b.length - ix);
        }
        is.close();
        return b;
    }
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        byte[] b = load("C:\\X.class");
        SpecialClassLoader scl = new SpecialClassLoader();
        scl.add("test.X", b);
        Object o = Class.forName("test.X", true, scl).newInstance();
        System.out.println(o);
    }
}

class SpecialClassLoader extends ClassLoader {
    private Map<String, byte[]> m = new HashMap<String,byte[]>();
    public void add(String clznam, byte[] code) {
        m.put(clznam, code);
    }
    protected Class<?> findClass(String name) {
        byte[] bc = m.get(name);
        return defineClass(name, bc, 0, bc.length);
    }
}
Avatar billede kernelx Juniormester
11. juni 2009 - 15:30 #6
genialt ... tak!
husk at skrive et eller andet som svar.

er det så også muligt at "unloade" en class?
eller kan jeg nøjes med at remove denne binary-class-entry i
min HashMap?


class SpecialClassLoader extends ClassLoader {
    private Map<String, byte[]> m = new HashMap<String,byte[]>();

    public void remove( String clznam ) {
      // unloadClass( m.get( clznam ) );
      m.remove( clznam );
    }

    public void add(String clznam, byte[] code) {
        m.put(clznam, code);
    }
    protected Class<?> findClass(String name) {
        byte[] bc = m.get(name);
        return defineClass(name, bc, 0, bc.length);
    }
}
Avatar billede arne_v Ekspert
11. juni 2009 - 15:58 #7
For at unloade en class mener jeg at du er noedt til at fjerne classloaderen.
Avatar billede arne_v Ekspert
11. juni 2009 - 15:59 #8
Og svar.
Avatar billede arne_v Ekspert
11. juni 2009 - 15:59 #9
fjerne classloaderen = fjerne instansen af classloaderen
Avatar billede arne_v Ekspert
11. juni 2009 - 21:52 #10
Hvis clients ikke er 100% lad os kalde det paalidelige, saa boer du nok saette en security manager.
Avatar billede kernelx Juniormester
12. juni 2009 - 11:45 #11
mange mange tak!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester