# Klasse String erweitern mit AspectJ



## FlorianJo (30. Sep 2010)

Hallo,
Mit AspectJ ist man ja in der Lage mittels Intertype Declaration Klassen zu erweitern. Jedoch hab ich das bisher nur bei Klassen geschafft, für die ich auch Source habe. Also für Selbstdefinierte Klassen.
Nun möchte ich gerne andere, fremde Bibliotheken auch erweitern können, ohne den Source code anfasse zu müssen.

Ich hätte nun gedacht, dass ich mit folgenden code die String Klasse erweitern kann.

```
public aspect MyString {
	
	public String java.lang.String.reverse(){
		StringBuffer s = new StringBuffer(this);
		return s.reverse().toString();
	}
}
```

Zum Einen bekomme ich eine Warnung im Aspect MyString:
this affected type is not exposed to the weaver: java.lang.String [Xlint:typeNotExposedToWeaver]

Wenn ich die Methode versuche auszuführen, bekomme ich folgende Exception:
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.String.reverse()Ljava/lang/String;
	at MyString.ajc$interMethodDispatch1$mypackage_MyString$java_lang_String$reverse(MyString.aj)

Ich denke, dass es daran liegt, dass die String Klasse halt nur als .jar vorliegt und nicht als .java.
Hat jemand das Problem schon mal gelöst? 

Gruß Florian


----------



## Atze (30. Sep 2010)

es hat imho noch nie jemand versucht, weil string final ist! 

obs mit krücke geht weiß ich nicht, bzw wie du mit aspectJ möglich ist. halte ich aber für unnötig, weil string fertig ist, so wie es ist!  sonst wäre sie nicht final!


----------



## FlorianJo (30. Sep 2010)

Da hast du schon recht, dass die String Klasse fertig ist
String war ja nur ein Beispiel. Ich möchte halt allgemein wissen, ob man Bibliotheken erweitern kann, ohne selbst die Sourcen haben zu müssen. Dann könnte man fremde .jar´s nach eigenen Wünschen erweitern.

Gruß Florian


----------



## Atze (30. Sep 2010)

vielleicht ist das ganricht gewünscht, wenn jemand die sourcen nicht rausgibt!


----------



## FlorianJo (30. Sep 2010)

hehe, ich weiß was du meinst 
Ich komme überhaupt auf diese Möglichkeit, da ich im Buch: AOP mit AspectJ 5 von Oliver Böhm gelesen habe, dass dies möglich sei. Jedoch gab es kein konkretets Beispiel.


----------



## Atze (30. Sep 2010)

wenn ich zeit hab schau ich auch mal rein, aber bis jetzt hatte ich aop noch nie eim einsatz! nur n pdf überflogen bisher. momentan stellt sich mir aber noch die frage nach dem sinn vom erweitern von klassen, die ich nicht kenne, bzw wovon er keinen source gibt!


----------



## Noctarius (30. Sep 2010)

Nutz für sowas lieber nicht AspectJ. String kannst du nur erweitern, wenn du schon einen Java-Agent in der Runtime selber registrierst, da die Klasse bereits durch den SystemClassLoader geladen wird. An dieser Stelle kannst du nur über einen Agent eingreifen.

Eine andere Variante ist die Scala-Version. Diese haben eine Klasse gebastelt die String zwar nicht ableitet aber CharSequence und ExtendedString (oder so) heißt. Die Scala Runtime setzt selber automatisch für jeden String einen ExtendedString ein, in Java müsstest du das von Hand machen oder per Bytecode Enhancement.

Diese Klasse ExtendedString stellt jetzt quasi einen Wrapper auf den original String bereit (wird z.B. per Konstruktor übergeben) und fügt neben den Standard-Methoden der Klasse String (welche durchgereicht werden), zusätzliche neue Methoden bereit.


----------



## FlorianJo (30. Sep 2010)

hmmm...das hört sich ja gut kompliziert an^^
Ich hab in Scala immer mit implicits gearbeitet, wenn ich Methoden zur ein bestehenden Klasse, wie Integer oder String hinzufügen wollte.
Ich hab echt gedacht, dass mit aspectJ dies geht. Vorallem, weil der Author Oliver Böhm in seine Buch dies geschrieben hat  (S. 159).
Ich hatte gehofft, dass der AspectJ- Weaver dies hinbekommt.


----------



## Noctarius (30. Sep 2010)

Wenn der AspectJ Weaver in Kombination mit einem Java-Agent läuft geht das auch aber generell würde ich davon absehen, weil du zur Programmierzeit keine Möglichkeit hast auf die neuen Möglichkeiten der Klassen zuzugreifen.


----------

