Avatar billede kernelx Juniormester
13. marts 2009 - 07:24 Der er 3 kommentarer og
1 løsning

Fra String med java til Java-Object

Hi,

hvordan kan jeg få fat i et java-object hvor java-coden står i en string?

Jeg har allerede stillet samme spørgsmål en anden gang.
http://www.eksperten.dk/spm/842708
Der var to løsninger til dette problem. Og min løsning sidste gang var at skrive javascript-code.

Er der nogen som kan give mig et simpelt eksempel på at få java-code i en string - til et java-object?

++++++++++++++++++
public interface HelloInterface {
  public void sayHello();
}
++++++++++++++++++

++++++++++++++++++
String javaCode = "package test;\npublic class Test implements HelloInterface {\npublic void sayHello() { System.out.println( \"Hello\" ); }\n}";

HelloInterface helloObject = XYZ.parseJavaCode( javaCode );
helloObject.sayHello();
++++++++++++++++++


med venlig hilsen
KernelX
Avatar billede arne_v Ekspert
13. marts 2009 - 14:12 #1
Simpelt er et vanskeligt krav.

:-)

Men kig paa nedenstaaende kode:

package test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

public class JC {
    public static void dynamicCall(String clznam, String src, String cp, String metnam) throws Exception {
        SpecialClassLoader xcl = new SpecialClassLoader();
        compileMemoryMemory(src, cp, clznam, xcl, System.err);
        Class<?> c = Class.forName(clznam, true, xcl);
        Object o = c.newInstance();
        c.getMethod(metnam, new Class[] { }).invoke(o, new Object[] { });
    }
    public static void compileMemoryMemory(String src, String cp, String name, SpecialClassLoader xcl, PrintStream err) {
        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector<JavaFileObject> diacol = new DiagnosticCollector<JavaFileObject>();
        StandardJavaFileManager sjfm = javac.getStandardFileManager(diacol, null, null);
        SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm, xcl);
        CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays.asList(new String[] { "-classpath", cp }), null,
                                                Arrays.asList(new JavaFileObject[] { new MemorySource(name, src) }));
        boolean status = compile.call();
        if(err != null) {
            err.println("Compile status: " + status);
            for(Diagnostic<? extends JavaFileObject> dia : diacol.getDiagnostics()) {
                err.println(dia);
            }
        }
    }
}

class MemorySource extends SimpleJavaFileObject {
    private String src;
    public MemorySource(String name, String src) {
        super(URI.create("string:///" + name.replace(".", "/") + ".java"), Kind.SOURCE);
        this.src = src;
    }
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        return src;
    }
    public OutputStream openOutputStream() {
        throw new IllegalStateException();
    }
    public InputStream openInputStream() {
        return new ByteArrayInputStream(src.getBytes());
    }
}

class MemoryByteCode extends SimpleJavaFileObject {
    private ByteArrayOutputStream baos;
    public MemoryByteCode(String name) {
        super(URI.create("byte:///" + name.replace(".", "/") + ".class"), Kind.CLASS);
    }
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        throw new IllegalStateException();
    }
    public OutputStream openOutputStream() {
        baos = new ByteArrayOutputStream();
        return baos;
    }
    public InputStream openInputStream() {
        throw new IllegalStateException();
    }
    public byte[] getBytes() {
        return baos.toByteArray();
    }
}

class SpecialJavaFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
    private SpecialClassLoader xcl;
    public SpecialJavaFileManager(StandardJavaFileManager sjfm, SpecialClassLoader xcl) {
        super(sjfm);
        this.xcl = xcl;
    }
    public JavaFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
        name = sibling.getName().substring(1, sibling.getName().length() - 5).replace("/", ".");
        MemoryByteCode mbc = new MemoryByteCode(name);
        xcl.addClass(name, mbc);
        return mbc;
    }
}

class SpecialClassLoader extends ClassLoader {
    private Map<String,MemoryByteCode> m;
    public SpecialClassLoader() {
        super(SpecialClassLoader.class.getClassLoader());
        m = new HashMap<String, MemoryByteCode>();
    }
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        MemoryByteCode mbc = m.get(name);
        if(mbc != null) {
            return defineClass(name, mbc.getBytes(), 0, mbc.getBytes().length);
        } else {
            throw new ClassNotFoundException(name);
        }
    }
    public void addClass(String name, MemoryByteCode mbc) {
        m.put(name, mbc);
    }
}
Avatar billede arne_v Ekspert
13. marts 2009 - 18:46 #2
c.getMethod(metnam, new Class[] { }).invoke(o, new Object[] { });

kan erstattes af

return o;

hvis det passer bedre.
Avatar billede kernelx Juniormester
03. april 2009 - 11:28 #3
mange tak!
husk at skrive et eller andet som svar.
Avatar billede arne_v Ekspert
03. april 2009 - 14:56 #4
svar
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

IT-JOB

Metroselskabet og Hovedstadens Letbane

Data Engineer at Metroselskabet

Forsvarsministeriets Materiel- og Indkøbsstyrelse

BI-koordinator / IT & administrativ support