Avatar billede p_gaard Juniormester
21. oktober 2008 - 10:53 Der er 1 kommentar og
1 løsning

Apache - Java ClassLoader problem

Nedenstående java kode fungerer fint når det afvikles inde i eclipse. Der oprettes en klasse i memory som efterfølgende kompileres og der kaldes en metode.

Der opstår til gengæld et problem når jeg kører klassen i Tomcat (WEB-INF/pkkcms_lib). Java version i apache sat til jdk1.6.0_010.

Følgende fremgår af apache's consol:

compile-status:true
NullPointerException
      at SpecialClassLoader.findClass(JC16.java:195)
      at java.lang.classLoader.loadClass(ClassLoader.java:307)
      ...
      ...

- Det ser ud til at klassen kompileres fint. Problemet opstår efterfølgende i linjen "Class<?> c = Class.forName("content", false, xcl);".


---------------------------------------------------------------


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 java.io.*;

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 JC16x {


    public static void testMemoryMemory() throws Exception {
        //String cx=ReadTextFile.readTextFile(new File("C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/pkkcms/WEB-INF/pkkcms_lib/content.java"),"cp1252").toString();
       
        // denne tekstfil skal senere nedlægges og kun oprettes som streng.
        String cx=ReadTextFile.readTextFile(new File("C:/dmi/java2/pkkcms_268/content.java"),"cp1252").toString();
        String src = cx;
        SpecialClassLoader xcl = new SpecialClassLoader();
        compileMemoryMemory(src, "content", xcl, System.err);
        Class<?> c = Class.forName("content", false, xcl);
        Object o = c.newInstance();
        c.getMethod("content", new Class[] {}).invoke(o, new Object[] { });

    }
    public static void compileMemoryMemory(String src, 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", "C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/pkkcms/WEB-INF/pkkcms_lib"}), null,
        //                                        Arrays.asList(new JavaFileObject[] { new MemorySource(name, src) }));
        CompilationTask compile = javac.getTask(null, xfm, diacol, Arrays.asList(new String[] {"-classpath", "C:/dmi/java2/pkkcms_268/"}), 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 + ".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 + ".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 {
        MemoryByteCode mbc = new MemoryByteCode(name);
        xcl.addClass(name, mbc);
        return mbc;
    }
}

class SpecialClassLoader extends ClassLoader {
    private Map<String,MemoryByteCode> m;
    public SpecialClassLoader() {
        m = new HashMap<String, MemoryByteCode>();
    }
    protected Class<?> findClass(String name) {


        MemoryByteCode mbc = m.get(name);
        return defineClass(name, mbc.getBytes(), 0, mbc.getBytes().length);
    }
    public void addClass(String name, MemoryByteCode mbc) {
        m.put(name, mbc);
    }
}
Avatar billede arne_v Ekspert
25. oktober 2008 - 04:41 #1
Jeg har svaret her:
  http://www.eksperten.dk/spm/850081
så luk bare her.
Avatar billede p_gaard Juniormester
27. oktober 2008 - 13:51 #2
Tak! det vil jeg prøve.
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