Avatar billede jespersahner Nybegynder
26. februar 2005 - 11:31 Der er 6 kommentarer og
1 løsning

ClassLoader-problem

Flg. kode er oprindelig inspireret af bla. http://eksperten.dk/spm/410887.

Den flg. kodestump:

import java.io.*;
import java.net.*;

public class Classloading {
    private static void dynno(int n) {
        try {
            OutputStream os = new FileOutputStream("test/Test.java");
            PrintStream ps = new PrintStream(os);
            ps.println("public class Test {");
            ps.println("  public Test() {");
            ps.println("      System.out.println(" + n + ");");
            ps.println("  }");
            ps.println("}");
            ps.close();
            os.close();
            Runtime.getRuntime().exec("javac test/Test.java").waitFor();
            URLClassLoader cl = new URLClassLoader(new URL[]{new URL("file:test/")});
            cl.loadClass("Test").newInstance();           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        (new File("test")).mkdir();
        for(int i = 0; i < 10; i++) {
            dynno(i);
        }
    }
}

- virker og udskriver 0 1..9.

Jeg prøver nu at ændre en smule i koden ved at indføre nogle package-statements:

package Classloading;

import java.io.*;
import java.net.*;

public class Classloading {
    private static void dynno(int n) {
        try {
            OutputStream os = new FileOutputStream("c:/Classloading/Test.java");
            PrintStream ps = new PrintStream(os);
            ps.println("package Classloading;");
            ps.println("public class Test {");
            ps.println("  public Test() {");
            ps.println("      System.out.println(" + n + ");");
            ps.println("  }");
            ps.println("}");
            ps.close();
            os.close();
            Runtime.getRuntime().exec("javac -classpath c:/ c:/Classloading/Test.java").waitFor();
            URLClassLoader cl = new URLClassLoader(new URL[]{new URL("file:c:/Classloading/")});
            cl.loadClass("Classloading.Test").newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        for(int i = 0; i < 10; i++) {
            dynno(i);
        }
    }
}

- men nu udskriver programmet kun lutter 0'er, altså 0 0..0.

Det er som om, at programmet kun load'er den første klasse-definition eller bruger samme classloader hver gang eller..

Hvad kan der være galt her?
Avatar billede arne_v Ekspert
26. februar 2005 - 11:36 #1
URLClassLoader cl = new URLClassLoader(new URL[]{new URL("file:c:/Classloading/")});

skal ihvertfald være

URLClassLoader cl = new URLClassLoader(new URL[]{new URL("file:c:/")});
Avatar billede arne_v Ekspert
26. februar 2005 - 11:37 #2
Og det er tit vigtigt at den classpath du loader dynamisk fra *IKKE* er i
classpath for det program der driver det hele.
Avatar billede jespersahner Nybegynder
26. februar 2005 - 11:43 #3
->arne_v: 11:36 Ja, det må jeg give dig ret i. Det giver dog ikke noget at ændre.
->arne_v: 11:37 Hmm..måske har du fat i noget her, men hvorfor egentlig ikke?
Avatar billede arne_v Ekspert
26. februar 2005 - 11:45 #4
classloadere er struktueret hirakisk og der søges fra oven af ikke fra neden af.

D.v.s. at classloaderen som har loader Classloadin.Classloading bliver spurgt
først om den kan finde Classloading.Test inden cl bliver spurgt.
Avatar billede arne_v Ekspert
26. februar 2005 - 11:51 #5
Ja - det er nok det som er problemet.

Hvis dit driver program ligger i og køres fra C:/ så kan din
originale classloader loade den dynamisk genererede klasse.

Og når den er loadet første gang bliver den ikek smidt ud igen.

Det gør den med cl, fordi en klasse er implicit prefixed med classloaderen
d.v.s. at når du loader med en ny classloader så er det automatisk en ny klasse.
Avatar billede jespersahner Nybegynder
26. februar 2005 - 14:02 #6
->arne_v: Jamen, du har jo ganske ret! Når jeg placerer den dynamiske klasse i en mappe udenfor classpath for mit hovedprogram, kan hovedprogrammet ikke "se" den dynamiske klasse, og så går det godt.

Jeg takker mange gange for dit (altid) hurtige og kompetente svar!

Smid straks et svar.
Avatar billede arne_v Ekspert
26. februar 2005 - 14:06 #7
kommer her
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