Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Klassen überladen

0 views
Skip to first unread message

Andre

unread,
Jun 20, 2004, 4:03:20 AM6/20/04
to
Hallo,
das Zile meiner Bemühungen ist die Manipulation der von Ant benutzten
(OS) Systemvariablen. Ant benutzt zur Ermittlung dieser die Klasse
Execute, welche ein "cmd set" macht und das Ergebnisse auswertet. Also
bin ich auf die Idee gekommen meine eigene Execute Klasse zu schreiben
welche im Classpath vor der Ant Klasse liegt und somit von Ant genutzt
wird. Um auf die Funktionen der orginal Klasse zurück zugreifen, lade
ich mir die orginal Klasse mit einen JarClassLoader aus dem ant.jar und
leite alle public Methoden meiner Execute Klasse via Reflection an die
Orginal Klasse weiter. Soweit die Theorie, es funktioniert aber nicht.
Beim Versucht die orginal Klasse zu nutzen bekomme ich eine
IlligalAccess Exception, kann sich das jemand erklären ?
Dann wäre da noch was, versuche ich die Klasse noch einmal aus dem Jar
zu laden, herhalte ich einen Fehler, dass die Klasse bereits definiert
ist, gibt es eine Möglichkeit den Klassennamen zuändern, wie es bei der
Proxy Api gemacht wird ?

Danke, ich wäre sehr dankbar für Ideen oder Vorschläge.


Andre

Nico Seessle

unread,
Jun 20, 2004, 4:53:36 AM6/20/04
to
Andre wrote:

> das Zile meiner Bemühungen ist die Manipulation der von Ant benutzten
> (OS) Systemvariablen.

Frage voweg: Wozu soll das gut sein?

> Soweit die Theorie, es funktioniert aber nicht. Beim Versucht die
> orginal Klasse zu nutzen bekomme ich eine IlligalAccess Exception,
> kann sich das jemand erklären ?

Höchstens aus der Doku vorlesen:

"An IllegalAccessException is thrown when an application tries to
reflectively create an instance (other than an array), set or get a
field, or invoke a method, but the currently executing method does not
have access to the definition of the specified class, field, method or
constructor. "

Evtl. versuchst du also per Reflection irgendwas aufzurufen, was nicht
public ist (du könntest vorher noch setAccessible(true) aufrufen um das
zu umgehen, aber die Wahrscheindlichkeit das sich die private
Schnnittstelle einer Klasse ändert ist deutlich höher, als das es die
public-Schnittstelle tut, so das du evtl. deine Klasse bei jedem neuen
Ant-Release anpassen musst)

Geneauer geht das ohne Stack-Trace und Code-Schnipsel nicht.

Nico

Andre

unread,
Jun 20, 2004, 11:41:47 AM6/20/04
to
> Geneauer geht das ohne Stack-Trace und Code-Schnipsel nicht.
>
> Nico

Ok. Hier ist ein bißchen Code, vielleicht kommt ja dann eine Idee.

Der ClassLoader mit dem ich die Ant orginal Klasse aus dem Jar lade.

private byte[] getResourceAsByteArray( final String fileName )
[...]

public Class forName( final String className ) throws IOException {

final byte[] code = getResourceAsByteArray( className );

return defineClass( className, code, 0, code.length );
}

Und hier die Klasse welche ich überladen möchte.

package org.apache.tools.ant.taskdefs;
[...]
public class Execute {
static Class clazz = AntExecuteLoader.getAntExecuteClass();

static final private HashMap methodMap = new HashMap();

static {

final Method[] methods = clazz.getMethods();

for ( int i = 0; i < methods.length; i++ ) {
methodMap.put( methods[i].getName(), methods[i] );
}
}
[...]
public static synchronized Vector getProcEnvironment() {

final String METHOD_NAME = "getProcEnvironment";

Method method = ( Method ) methodMap.get( METHOD_NAME );

try { // hier kommt die Exception
return ( Vector ) method.invoke( null, null );
} catch ( Throwable e ) {
[...]

public static void main(final String args[] ) {
System.out.println( Execute.getProcEnvironment() );
}


Exception Trace :

java.lang.IllegalAccessError: tried to access class
org.apache.tools.ant.taskdefs.ProcessDestroyer from class
org.apache.tools.ant.taskdefs.Execute
at org.apache.tools.ant.taskdefs.Execute.<clinit>(Execute.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:324)
at
org.apache.tools.ant.taskdefs.Execute.getProcEnvironment(Execute.java:74)
at org.apache.tools.ant.taskdefs.Execute.main(Execute.java:382)

Die orginal Klasse hat eine static Teil :
private static ProcessDestroyer processDestroyer = new ProcessDestroyer();

Ich habe den Verdacht dass die Exception hierher kommt, aber wieso ?

Hat vielleicht jemand eine Idee oder ein Tip ?

Andre


0 new messages