Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[java]Dynamic Proxy zonder interface

Pagina: 1
Acties:

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Ik wil het volgende... Ik heb een berg classes die allemaal de zelfde interface implementeren, welke gewoon leeg is, puur om aan te geven dat de classes op de een of andere manier toch met elkaar verbonden zijn ;)
Verder zijn er een berg getters en setters, en wat annotations, maar die laatste zijn even niet zo belangrijk, laat ik dus maar even weg. Zoiets dus bijvoorbeeld:

Java:
1
2
3
4
5
6
7
public class Aap implements DierentuinDier{
    public String getNaam(){...}

    public void setNaam(String naam){..}

    ... meer meuk ...
}


Wat ik nu wil, zijn methodeaanroepen naar getNaam en setNaam dynamisch afvangen. Dat kan prima in Java, probleem is alleen dat je daarvoor een interface nodig hebt. En dat is nu precies dat ik niet wil ;) Er zijn namelijk nogal wat van die Aap classen, en om voor iedere ook nog weer een Interface te maken is gewoon zonde. Liever niet dus!

Goed... Die java.lang.reflect.Proxy verwacht dus een interface. Die kan ik natuurlijk wel maken. Heb dus wat code gemaakt om dynamisch een interface Class te maken met alle public methoden van de oorspronkelijke classe, evenals een implementatie hiervan, en het geheel dynamisch te compileren en te laden.

Java:
1
2
3
4
5
6
public interface InterfaceAap implements DierentuinDier{

   public String getNaam();

    public void setNaam(String naam);
}


Java:
1
2
public class ProxyAap extends Aap implements InterfaceAap {
}


Allemaal mooi en aardig... maar hier heb ik niets aan...

Als ik namelijk met Proxy.newProxyInstance een Proxy aanmaak krijg ik iets van type InterfaceAap terug. In mijn applicatie gebruik ik echter gewoon Aap. Helaas implementeert Aap InterfaceAap niet :'(

Wat ik dus zoek is een manier om dit toch voor elkaar te krijgen...

Ik heb een oud topic gevonden uit 2004 met een vergelijkbaar probleem, maar helaas vind ik ook daar mijn antwoord niet.

Een mogelijke oplossing van het probleem zou kunnen zijn om in ProxyAap alle methodes nogmaals te implementeren, en via die wel een eigen invocationhandler aanroepen. Dat is best nasty, maar misschien de enige weg (buiten het gebruik van interfaces).

Misschien hebben jullie nog een idee :?

Do diamonds shine on the dark side of the moon :?


  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 08-11 11:11
voodooless schreef op maandag 06 oktober 2008 @ 20:53:
Wat ik nu wil, zijn methodeaanroepen naar getNaam en setNaam dynamisch afvangen. Dat kan prima in Java, probleem is alleen dat je daarvoor een interface nodig hebt. En dat is nu precies dat ik niet wil ;) Er zijn namelijk nogal wat van die Aap classen, en om voor iedere ook nog weer een Interface te maken is gewoon zonde. Liever niet dus!
Zou je dit iets beter uit kunnen leggen? Voornamelijk het 'dynamisch afvangen' gedeelte. Ook begrijp ik niet helemaal vwat je bedoelt met 'nogal wat van die Aap classen' en dat voor elk daarvan een interface gemaakt moet worden...

Ik heb het idee dat het allemaal wat simpeler kan - maar dan is het wel handig 'the big picture' in mn hoofd te hebben.

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Ik wil gewoon weten als bijvoorbeeld getNaam() wordt aangeroepen, en daar ook eventueel een actie aan hangen, net als kan met de InvocationHandler interface i.c.m Proxies, zonder dat ik de implementaties allemaal eerst een interface moet laten implementeren waar weer de zelfde methodes in gedeclareerd zijn.

Wat ik bedoel met 'nogal wat van die Aap classen': er is vast ook nog een Paard, Egel, WindZwijn, Spin, Worm... enz... (dit is natuurlijk geen serieus voorbeeld, maar spreekt wel tot de verbeelding ;) ).

Ik heb het nu voor elkaar op een zeer ranzige manier door zelf zo'n Proxy classe te maken (letterlijk java code genereren, compileren en laden), maar ik denk nog steeds dat het makkelijker moet kunnen.

Do diamonds shine on the dark side of the moon :?


  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 08-11 11:11
Is het dan niet handig om Abstracte klassen te gebruiken? Dan maak je bijvoorbeeld een abstracte klasse 'Dier', met de getNaam() en zo als abstracte methodes. Maar, die maak je private.

In je abstracte klasse maak je een publieke versie van getNaam() - bijvoorbeeld getDierNaam(), die achter de schermen de implementatie-specifieke getNaam() aanroept. Die komt dus aan bij 'Aap', die extends van je abstracte klasse 'Dier'.

Mochten mijn bedoelingen niet duidelijk zijn roep dan ff dan probeer ik snel wat in notepad the kloppen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14-11 23:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als je al geinstantieerde classes hebt heb je sowieso niets aan de Proxy, want daarmee maak je nieuwe instances. Je kunt niet een al bestaande instance ermee wrappen. En vziw kun je met Java reflection niet bestaande instances aanpassen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
.oisyn schreef op maandag 06 oktober 2008 @ 23:16:
Als je al geinstantieerde classes hebt heb je sowieso niets aan de Proxy, want daarmee maak je nieuwe instances. Je kunt niet een al bestaande instance ermee wrappen. En vziw kun je met Java reflection niet bestaande instances aanpassen.
Dat is inderdaad precies het probleem ;) Maar die instantie heb ik in eerste instantie ( ;) ) nog helemaal niet. I.p.v de instantie wil ik gewoon een wrapper terug geven. Dat heb ik dus nu voor elkaar door er eentje zelf dynamisch te compileren, maar deze oplossing is natuurlijk verre van netjes..

Abstracte classes win ik niets mee, dan kan ik net zo goed interfaces maken en de Proxy gebruiken.

Do diamonds shine on the dark side of the moon :?


  • Salandur
  • Registratie: Mei 2003
  • Laatst online: 15-11 08:29

Salandur

Software Engineer

misschien moet je dan opzoek naar bytecode enhancers, zoals een AOP implementatie die dit ondersteund. Dan wordt je code na het compilen of runtime aangepast zodat je het gewenste gedrag krijgt.

AspectJ is hier een goede optie in.

[ Voor 9% gewijzigd door Salandur op 07-10-2008 09:28 ]

Assumptions are the mother of all fuck ups | iRacing Profiel


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Zou kunnen, maar is wel erg ingrijpend voor het doel dat ik voor ogen heb.

Do diamonds shine on the dark side of the moon :?


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Dat klopt, maar dat komt vooral omdat de normale (als in 'minder ingrijpende' manier) degene is waarbij je deze methoden ook in je interface zet.

Ik vermoed trouwens dat er nog iets in je voorbeeld mist. Het lijkt me namelijk dat alle dierentuin dieren wel een naam hebben en dat het helemaal geen probleem zou moeten zijn om die methoden dus in de interface te zetten.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 08-11 11:11
Janoz schreef op dinsdag 07 oktober 2008 @ 10:04:
Ik vermoed trouwens dat er nog iets in je voorbeeld mist. Het lijkt me namelijk dat alle dierentuin dieren wel een naam hebben en dat het helemaal geen probleem zou moeten zijn om die methoden dus in de interface te zetten.
Dat is waar ik ook tegenaan liep - ik mis the big picture. Ik zie niet wat er moet worden bereikt.
Als je alleen wilt weten wanneer een getNaam() methode wordt aangeroepen kan je dat of via de voorgestelde abstracte methode implementeren - of via een observer constructie.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14-11 23:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

voodooless schreef op dinsdag 07 oktober 2008 @ 08:36:
[...]


Dat is inderdaad precies het probleem ;) Maar die instantie heb ik in eerste instantie ( ;) ) nog helemaal niet. I.p.v de instantie wil ik gewoon een wrapper terug geven.
Nou dat leek helemaal niet het probleem, het probleem leek te zijn dat er geen common interface was met de juiste methoden. Je eerste deel van je startpost wekt dus wat verwarring imho, als dat het probleem niet is. Verder eens met bovenstaande, er lijkt wat cruciale info te missen :)

[ Voor 24% gewijzigd door .oisyn op 07-10-2008 11:42 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
voodooless schreef op maandag 06 oktober 2008 @ 20:53:
Wat ik nu wil, zijn methodeaanroepen naar getNaam en setNaam dynamisch afvangen. Dat kan prima in Java, probleem is alleen dat je daarvoor een interface nodig hebt. En dat is nu precies dat ik niet wil ;) Er zijn namelijk nogal wat van die Aap classen, en om voor iedere ook nog weer een Interface te maken is gewoon zonde. Liever niet dus!
Hoe worden je classes gemaakt? Met de hand of worden ze gegenereerd?

Wat is precies de reden dat je geen interfaces wilt hebben? Als je code gegenereerd word kan je natuurlijk ook gewoon interfaces mee laten genereren. Als je geen interfaces wilt omdat het teveel type werk is kun je in de meeste moderen IDE's ook wel gewoon een interface extracten uit een class. Ik zie dus nog niet precies in waarom die interfaces een probleem zijn?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Janoz schreef op dinsdag 07 oktober 2008 @ 10:04:
Ik vermoed trouwens dat er nog iets in je voorbeeld mist. Het lijkt me namelijk dat alle dierentuin dieren wel een naam hebben en dat het helemaal geen probleem zou moeten zijn om die methoden dus in de interface te zetten.
Zoals ik zei, het is een voorbeeld. In de praktijk gaat dit argument niet op.

De classes worden gewoon met de hand gemaakt. Natuurlijk kun je dan weer overal interfaces voor gaan schrijven of laten genereren. Misschien is dat toch ook wel weer een mogelijke oplossing.. Eens over nadenken.

[ Voor 20% gewijzigd door voodooless op 07-10-2008 12:53 ]

Do diamonds shine on the dark side of the moon :?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14-11 23:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Maar hoe lost het hebben van een interface je probleem dan op? En waarom lost die ProxyAap class je probleem dan niet op?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
.oisyn schreef op dinsdag 07 oktober 2008 @ 12:55:
Maar hoe lost het hebben van een interface je probleem dan op? En waarom lost die ProxyAap class je probleem dan niet op?
Omdat alleen de ProxyAap de interface InterfaceAap implementeerd en niet de Aap class. In zijn applicatie gebruikt hij Aap en kan die dus niet assignen met een InterfaceAap.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Misschien moeten we even een niveau terug omhoog stappen: welk probleem probeer je op te lossen? Zijn proxies en 'dynamisch methodeaanroepen afvangen' wel de goede oplossing voor je probleem? Voordat je er straks achterkomt dat je het met wat kunstgrepen wel met proxies op kan lossen, maar dat er eigenlijk een betere oplossing voor is.

Overigens is 'bytecode enhancement', bijvoorbeeld het dynamisch toevoegen van methoden aan een klasse, IMHO helemaal niet zo ingrijpend.

[ Voor 42% gewijzigd door Confusion op 07-10-2008 13:08 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14-11 23:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

rwb schreef op dinsdag 07 oktober 2008 @ 13:02:
[...]

Omdat alleen de ProxyAap de interface InterfaceAap implementeerd en niet de Aap class. In zijn applicatie gebruikt hij Aap en kan die dus niet assignen met een InterfaceAap.
Dat doet ie wel:
public class ProxyAap extends Aap implements InterfaceAap { }

.edit: ooh wacht, laat maar, ik ben dom aan het denken. Hij instantieert natuurlijk niet een ProxyAap, maar een Proxy die InterfaceAap implementeert. De hele ProxyAap class is dus vrij nutteloos. 8)7

[ Voor 21% gewijzigd door .oisyn op 07-10-2008 13:13 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
.oisyn schreef op dinsdag 07 oktober 2008 @ 13:10:
De hele ProxyAap class is dus vrij nutteloos. 8)7
Precies ;) Tenzei je in deze de methodes zelf wrapt en dan deze instantie terug geeft. Dat werkt ook wel, is alleen niet erg mooi en ook niet erg flexibel.

Om terug te komen op de vraag van Confusion. Wat ik wil doen is runtime vaststellen of data in classes veranderd zijn vanaf een bepaald moment. Dit zou ik dan willen doen door alle setters af te vangen.

Andere methode zou kunnen zijn door ergens in een cache de hashcodes op te slaan (men moet dan hashCode() wel goed implementeren), en deze dan te vergelijken op het moment dat het nodig is...

Do diamonds shine on the dark side of the moon :?


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 14-11 08:26

bomberboy

BOEM!

voodooless schreef op dinsdag 07 oktober 2008 @ 14:21:
Om terug te komen op de vraag van Confusion. Wat ik wil doen is runtime vaststellen of data in classes veranderd zijn vanaf een bepaald moment. Dit zou ik dan willen doen door alle setters af te vangen.
Dat klinkt alsof je ergens een soort van (al dan niet in memory) datastore/database nodig hebt. Afhankelijk van wat je er allemaal mee wil doen natuurlijk.

Maar afgaande op wat er in de thread al allemaal gezegd is, wil je gewoon een aspect met een around-advice op alle set-methoden van je klassen. (en/of andere methoden met als neveneffect dat data veranderd wordt)
Indien je die geschiedenis wil bewaren heb je een soort van datastore nodig.

Althans, daar lijkt het op volgens wat ik er van begrijp.

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

voodooless schreef op dinsdag 07 oktober 2008 @ 14:21:
Om terug te komen op de vraag van Confusion. Wat ik wil doen is runtime vaststellen of data in classes veranderd zijn vanaf een bepaald moment. Dit zou ik dan willen doen door alle setters af te vangen.
De gangbare methode daarvoor is een Observer pattern, zoals je vaak 'PropertyChangeListeners' geimplementeerd ziet. Ervoor zorgen dat iedere setter een firePropertyChangedEvent() doet kan eventueel met code-generatie of bytecode manipulatie, als het met de hand teveel werk is.

Ik heb geen ervaring met aspects, maar volgens mij zijn die hier bij uitstek geschikt voor.

[ Voor 7% gewijzigd door Confusion op 07-10-2008 14:49 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Klinkt goed dat aspect met around-advice :) Ik zal er eens naar kijken morgen.

Natuurlijk zou een observer mooi zijn, maar standaard moet je daarvoor nogal veel doen, en het is nu net de bedoeling dat dit soort dingen gebeuren zonder dat de ontwikkelaar hier veel aan hoeft te doen.

[ Voor 57% gewijzigd door voodooless op 07-10-2008 19:35 ]

Do diamonds shine on the dark side of the moon :?


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 14-11 08:26

bomberboy

BOEM!

Je kan perfect dat observer pattern (of een variant) implementeren door aspecten te gebruiken hoor. Dan hoeft "de ontwikkelaar" daar helemaal geen rekening mee te houden. Dan heb je het beste van 2 werelden. Een standaard pattern gebruiken om je probleem op te lossen geniet meestal zowiezo de voorkeur. En dat je dit dan zou implementeren aan de hand van aspecten is daarbij niet zo belangrijk.

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Zie ik het nu goed dat ik voor aspectj nog steeds files moet genereren en compileren?

Do diamonds shine on the dark side of the moon :?


  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 08-11 11:11
voodooless schreef op dinsdag 07 oktober 2008 @ 21:17:
Zie ik het nu goed dat ik voor aspectj nog steeds files moet genereren en compileren?
Je kan AspectJ op drie verschillende manieren gebruiken

1) Je source met AspectJ support compilen.
2) Al gecompileerde class files hercompileren met AspectJ support.
3) Runtime de aspects in de classfiles compileren. (Load-time weaving)

Pik er een uit zou ik zeggen :)

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Nummer 3 zou ik zeggen... helaas is de documentatie alles behalve duidelijk wat dit punt betreft (in ieder geval dat wat ik tot nu toe gezien heb)...

edit: of toch ;)

edit2: Ik zie nog steeds dat ik een heleboel meuk aan mijn classes moet toevoegen om het werkend te maken, of kan het ook zonder?

[ Voor 45% gewijzigd door voodooless op 07-10-2008 21:54 ]

Do diamonds shine on the dark side of the moon :?


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

In het Spring framework kan je bijvoorbeeld transacties op twee manieren implementeren zonder iets aan de source te hoeven wijzigen: door proxies te configureren en door AspectJ crosscuts te configureren. In beide gevallen kan je dit toepassen op POJO's, zonder dat daar iets aan hoeft te wijzigen. Nu weet ik niet of AspectJ dit van zichzelf ook ondersteunt, maar als je in Spring kan zeggen "van alle klassen in dat package wil ik dat alle setters vóór invocation deze 'aspect' methode aanroepen", dan moet het met AspectJ niet zo gek lastig zijn, aangezien Spriong daar zwaar op leunt voor zijn crosscutting needs. Als dat om een of andere reden niet blijkt te werken, zou je nog even kunnen kijken hoe die transparante 'configure time' proxies in Spring werken.

[ Voor 12% gewijzigd door Confusion op 07-10-2008 22:06 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 08-11 11:11
voodooless schreef op dinsdag 07 oktober 2008 @ 21:45:
edit2: Ik zie nog steeds dat ik een heleboel meuk aan mijn classes moet toevoegen om het werkend te maken, of kan het ook zonder?
Het kan zonder. Heb het een hele tijd geleden ook een keer gebruikt om een klein 'pluggable' diagnostisch applicatietje te maken. Hierdoor hoefde ik de originele source van het systeem niet aan te passen, aangezien load-time wordt geweaved.

Hier een kleine samenvatting van wat ik ongeveer moest doen
  1. Een Aspect maken die voldeed aan mijn eisen, en natuurlijk de normale java code die daarop bouwt.
  2. Een xml (of was het properties) bestand aanmaken waarin ik aangaf welk aspects ik heb, en vanaf welke package ze moeten gaan 'hooken'. Deze moet onder een bepaalde naam in je jar komen.
  3. In de java parameters de agent instellen zodat de aspect weaver als agent wordt gebruikt. -Djavaagent was die param geloof ik, met als waarde het pad naar die weaver jar.
Kan zijn dat ik wat dingen mis maar dit staat allemaal gedocumenteerd.Weet je in ieder geval dat je goed zit als je bovenstaande stappen tegen komt.

[ Voor 0% gewijzigd door kw4h op 07-10-2008 22:10 . Reden: grammatica ftw ]


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Dat heeft toch wel relatief veel impact. De methode met de hashCode() is relatief veel eenvoudiger te implementeren in mijn geval.

Toch erg interessant om ooit een keer mee te spelen :)

[ Voor 18% gewijzigd door voodooless op 07-10-2008 23:11 ]

Do diamonds shine on the dark side of the moon :?


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

voodooless schreef op dinsdag 07 oktober 2008 @ 23:11:
Dat heeft toch wel relatief veel impact. De methode met de hashCode() is relatief veel eenvoudiger te implementeren in mijn geval.
hashCodes zijn niet gegarandeerd uniek, dus als je zeker moet weten of iets gewijzigd is, dan zijn ze niet bruikbaar (of je heel erg je best doet op de hashCode implementatie; ze zijn wel uniek te maken...). Bovendien zit je dan met een 'pull' mechanisme, terwijl de tot nu toe besproken varianten allemaal 'push' mechanismen zijn. Dat heeft als nadeel dat je met timers aan de slag moet en je informatie altijd verouderd is.

Wie trösten wir uns, die Mörder aller Mörder?


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Pull is good enough :) Er is slechts een punt waar ik moet weten of er iets veranderd is. Dat kan dus prima daar. Dat verkleind ook nog eens de overhead. Dat een hash niet gegarandeerd is, is waar. De kans dat het problemen gaat vormen acht ik echter extreem klein. Wat je bij een hash match nog zou kunnen doen is gewoon alle waardes nog met elkaar vergelijken om zeker te zijn dat er daadwerkelijk iets gewijzigd is. Als dat echter net zo lang duurt als het berekenen van de hashcode, kun je dat laatste natuurlijk ook vergeten ;).

Aan de slag met timers? Dat snap ik niet...

[ Voor 4% gewijzigd door voodooless op 08-10-2008 08:52 ]

Do diamonds shine on the dark side of the moon :?


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Met timers bedoelde ik 'op geregelde intervallen die pull doen'. Maar on-demand is natuurlijk prima.

Wat betreft waardes met elkaar vergelijken: als het niet teveel geheugen kost, kan je natuurlijk kopieen bijhouden en die on-demand met equals() vergelijken met de mogelijk gewijzigde versie.

Let bij de hashCode() implementatie overigens wel op dat je hashes dan wel de complete 4 miljard mogelijkheden zoveel mogelijk benutten. Ik ben weleens een hashCode() implementatie tegenkomen waarin gewoon twee int properties werden opgeteld...

Wie trösten wir uns, die Mörder aller Mörder?


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 14-11 21:45

voodooless

Sound is no voodoo!

Topicstarter
Confusion schreef op woensdag 08 oktober 2008 @ 09:19:
Let bij de hashCode() implementatie overigens wel op dat je hashes dan wel de complete 4 miljard mogelijkheden zoveel mogelijk benutten. Ik ben weleens een hashCode() implementatie tegenkomen waarin gewoon twee int properties werden opgeteld...
Mja, ik ben net aan het testen met diverse hash algoritmes. Onder andere ook MD5 en SHA256. Probleem hier is alleen de performance :'(

Edit: oplossing :) Maak van DierentuinDier een abstracte classe en implementeer hier toString() en hashCode() zodanig dat toString() altijd een voor de data unieke String teruggeeft, en hashCode() de hash van deze String. toString() loopt door alle getters heen en plakt de toString() waardes achter elkaar in een handig formaat. Aangezien ik voor andere doeleinden de Method van deze setters al heb kost dit ook erg weinig performance. Op een zelfde manier zou ik ook equals kunnen implementeren natuurlijk :)

[ Voor 33% gewijzigd door voodooless op 08-10-2008 12:53 ]

Do diamonds shine on the dark side of the moon :?


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Ik weet niet wat je eisen zijn, maar misschien denk je wel te moeilijk. Heb je de hashCode() implementatie van java.lang.String weleens bekeken? Of de hashCode() implementaties die Eclipse genereert als je daar om vraagt? Die zijn voor de meeste doeleinden afdoende.

Wie trösten wir uns, die Mörder aller Mörder?


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 14-11 08:26

bomberboy

BOEM!

voodooless schreef op dinsdag 07 oktober 2008 @ 21:45:
edit2: Ik zie nog steeds dat ik een heleboel meuk aan mijn classes moet toevoegen om het werkend te maken, of kan het ook zonder?
Persoonlijk heb ik nog geen gebruik gemaakt van load time weaving, maar je moet in ieder geval aan je classes zelf niets veranderen.

Een mogelijke pointcut voor jou zou iets zijn als:
Java:
1
2
 pointcut myExecutionPointCut(): execution(public * set*(..))
        && target(package.waar.je.klassen.toe.behoren);


Dat target is niet noodzakelijk. Ook kan je een call-pointcut gebruiken ipv een execution-pointcut maar in jouw geval is een execution-pointcut wenselijk denk ik.

En dan daarbij nog een around advice in de trant van:
Java:
1
2
3
4
5
6
7
8
9
10
Object around(): myExecutionPointCut() {
   //te bepalen door de huidige pointcut te bekijken, en de corresponderende getter op te vragen via reflectie
    Object val = previousVal; 
    Object t = proceed();
    //Op zelfde manier nieuwe waarde opvragen
    Object currentval = newval;
    if (! val.equals(currentval)) {
         doSomething();
    }
    return t;


Bovenstaande is onvolledige en uit het hoofd maar zou het idee moeten schetsen. Uiteraard ook rekening houden met mogelijke nulls enzo.
In ieder geval is dit voldoende om in een aspect te plakken en op je code los te laten voor compile time weaving. Voor runtime weaving moet je dan nog wat extra dingen definiëren zoals op welke classes die geladen worden dat aspect mag toegepast worden enz. Aan de bestaande classes moet je in principe niets aanpassen. Eventueel wel aan de classes die gebruik maken van de bekomen informatie, maar dat moet toch gebeuren.

Een uitgewerkt voorbeeldje van een subject-observer pattern implementatie met aspects is trouwens te vinden op:
http://www.eclipse.org/as...subject-observer-protocol

[ Voor 0% gewijzigd door bomberboy op 08-10-2008 10:36 . Reden: typo ]


  • NDF82
  • Registratie: Januari 2002
  • Laatst online: 09-11 11:40

NDF82

Doomed Space Marine

Wij hebben ook eens zoiets gemaakt met CGLib (net zoiets als java Proxy maar dan met support voor classes). Ons doel was in de eerste instatie een generieke observer; voor iedere setter die werd aangeroepen werd een PropertyChanged afgevuurd. Ik weet niet hoe aspectj werkt, maar CGLib werkt via reflectie en is daardoor heeeeeel traag. Wij hebben CGLib vervangen doo code generatie. Alle dieren worden gedefinieerd in een XSD en met JAXB worden classes gegenereerd. Onze eigen JAXB plugin genereert vervolgens de observer code + een boel meer (zoals equals(), deepEquals(), toString(), deepToString(), Visitors, blablabla).

Pentium 233MHz MMX + Diamond Monster 3D 3DFX Voodoo II

Pagina: 1