PROBLEM: Der PAManager der CIAgent-Software wirft bei Verwendung von Java 1.4 eine StringIndexOutOfBoundsException, sobald Agenten instantiiert werden sollen. Mit Java 1.3 funktioniert es jedoch. LÖSUNG: - die Methode addAgent in der Datei ciagent/CIAgent.java muss wie folgt bearbeitet werden (Änderungen an zwei Stellen): VORHER: public void addAgent(CIAgent child) { children.addElement(child) ; child.setParent(this) ; } NACHHER: public int addAgent(CIAgent child) { children.addElement(child) ; child.setParent(this) ; return 0; } - neu compilieren von ciagent/CIAgent.java: jay-jay@powerslave:~/stud/wbs/ciagent2e> javac ciagent/CIAgent.java - PAManagerApp starten -- jetzt müssten die Agenten korrekt geladen werden, die in ./pamanager.properties aufgelistet sind. jay-jay@powerslave:~/stud/wbs/ciagent2e> java pamanager/PAManagerApp (unter UNIX sind Dateinamen case sensitive, hier muss man diese .properties Datei auf jeden Fall mit Kleinbuchstaben benennen, MS-Windows ist es egal) URSACHE: Für die Interessierten, hier die Erklärung: In der Methode pamanager.PAManagerFrame.readPropertiesFile lässt sich mit einem weiteren catch-Block die Exception abfangen und verfolgen: DEBUG: Exception caught. java.lang.StringIndexOutOfBoundsException: String index out of range: -3 java.lang.StringIndexOutOfBoundsException: String index out of range: -3 at java.lang.String.substring(String.java:1480) at java.beans.Introspector.getTargetEventInfo(Introspector.java:861) at java.beans.Introspector.getBeanInfo(Introspector.java:371) at java.beans.Introspector.getBeanInfo(Introspector.java:144) at java.beans.Introspector.getBeanInfo(Introspector.java:205) at java.beans.Introspector.(Introspector.java:351) at java.beans.Introspector.getBeanInfo(Introspector.java:144) at ciagent.CIAgent.getDisplayName(CIAgent.java:302) at pamanager.PAManagerFrame.readPropertiesFile(PAManagerFrame.java:560) at pamanager.PAManagerFrame.(PAManagerFrame.java:75) at pamanager.PAManagerApp.(PAManagerApp.java:27) at pamanager.PAManagerApp.main(PAManagerApp.java:63) Nach längerem Studieren der Methode java.beans.Introspector.getTargetEventInfo() fällt einem folgende Stelle auf (siehe Java 1.4 source), an der die Methoden des JavaBeans dahingehend geprüft werden, ob sie eine `addFooListener'-Methode sind: if (name.startsWith(ADD_PREFIX) && argTypes.length == 1 && resultType == Void.TYPE && Introspector.isSubclass(argTypes[0], eventListenerType)) { String listenerName = name.substring(3); if (listenerName.length() > 0 && argTypes[0].getName().endsWith(listenerName)) { adds.put(listenerName, method); } } Und ein Stück weiter unten wird über diese `adds' Collection iteriert und dabei dies gerufen: String eventName = decapitalize( listenerName.substring(0, listenerName.length()-8)); Und genau bei dieser -8 liegt die Ursache: Die ursprüngliche addAgent-Methode erfüllt alle Bedingungen des if-Statements, d.h. sie beginnt mit `add' und hat genau einen Parameter und gibt `void' zurück; last but not least erwartet addAgent einen Parameter vom Typ CIAgent und CIAgent implementiert das Interface CIAgentEventListener, das wiederum java.util.EventListener erweitert, so dass auch die letzte Bedingung erfüllt ist. Damit aber nicht genug, auch die innere if-Bedingung ist true, da der erwartete Parameter-Typ CIAgent auf `Agent' endet. Es wird aber NICHT geprüft, ob der Methodenname auf `Listener' endet und weil dies nicht der Fall ist, können auch keine 8 Zeichen abgezogen werden und so entsteht eine StringIndexOutOfBoundsException. Fazit: Mit Java 1.4 schlägt die Introspection eines JavaBean unter ganz bestimmten Umständen fehl, da in der Methode getTargetEventInfo() der Klasse java.beans.Introspector eine Annahme getroffen wird, die zwar oft ausreichen wird, aber nicht in 100% aller Fälle korrekt ist. Die `Lösung', die ich oben beschrieben habe, ist also allenfalls ein Hack oder sagen wir Workaround, der verhindert, dass der Introspector die addAgent-Methode als EventListener betrachtet. [2003-10-10 Joachim Jautz]