Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt.
De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
15 comments
Voor iedereen die (net als ik) een [Inconsistent Module State] exception krijgt tijdens het deployen in Glassfish: zie
http://forums.java.net/jive/thread.jspa?threadID=14134&messageID=98688
Erwin Kooi
Thanks
Arianne van den Berg
Even een vraagje.
Als je bepaalde business logica zowel local als remote beschikbaar wil stellen, moet je dan 2 beans implementeren?
Zou op zich niet moeten, want de logica is hetzelfde. Maar in opdracht 1 hebben we een
CurrencyConverterRemote en CurrencyConverterLocal, hoe map je die naar dezelfde bean? Je kunt in de Bean maar 1 JNDI naam opgeven en de local en remote moeten toch eigen namen hebben; moet de namen dan in de interface gedeclareerd worden?
*** Dijk
Als basis voor het local en remote aanbieden van dezelfde functionaliteit is het gebruikelijk te kiezen voor een algemene interface waarvan je een local en een remote business interface afleidt. Uiteindelijk is er maar 1 bean implementatie, deze mag met behulp van het implements keyword net zoveel interfaces implementeren als hij maar leuk vindt.
Technisch gezien is het mogelijk om alles met 1 business interface op te lossen. Je geeft dan in deze ene interface aan dat deze zowel @Local als @Remote is. Maar dit is erg ambigue en daarom m.i. af te raden.
Zoals je kunt zien op slide 35 (Session Beans) zijn er meerdere manieren om de koppeling te maken tussen een bean implementatie class en zijn interface(s).
De JNDI naam heeft in deze helemaal niets te maken met de koppeling tussen bean en interfaces, maar is een identificatie ten behoeve van de client view.
berte
Gisteren heb ik de eerste opdracht van session beans gemaakt. Op een of andere manier krijg ik telkens een http 404 error omdat de autodeployment niet goed gaat. De ant build is successfull. De server log geeft de volgende error message: Could not expand entry null into destination C:glassfishdomainsdomain1applicationsj2ee-appsSessionBeansAppSessionBeans_jar
Waar kan dat aan liggen? Ik wil wel graag mijn tests bekijken….
Eelco Meuter
Een vraag over de installatie /configuratie van Eclipse:
In Eclipse worden bij mij de annotations niet herkend (levert een foutmelding op). Ik heb gecontroleerd of voor het project de goede JDK wordt gebruikt / compliance level is ingesteld op 5. Moet ik nog andere instellingen aanpassen om met annotations te kunnen werken?
Bob Kennedy
Heb je javaee.jar toegevoegd?
Eelco Meuter
@Bob
Zoals Eelco al suggereert lijkt het erop dat je vergeten bent om de javaee.jar toe te voegen aan het build path van je Eclipse project.
@Eelco
De foutmelding die je beschrijft doet vermoeden dat een van de benodigde archives leeg is, of niet wordt meegedeployed. Heb je je aan de voorgestelde naamgeving uit de labomschrijving gehouden? Een typo in de build.xml is natuurlijk ook snel gemaakt. Controleer eens of de jar, war en ear files die door het build script worden aangemaakt in de Eclipse project directory ook daadwerkelijk bestaan en worden gevuld met de juiste classes, etc.
berte
Bedankt bert! Het was inderdaad een typo in de application.xml. Ik heb de test servlet weer terug gebracht naar zijn ‘default style’ en de applicatie deployed. Deze keer krijg ik een http 503 error : SessionBeansApp:SessionBeansWEB.jar;java.lang.IllegalArgumentException: [ejb.CurrencyConvertor] is not an allowed property value type;_RequestID=e6f92b4c-6991-4dc4-b1bb-3985f9db8a7a;|WEB0123: WebModule [SessionBeansApp:SessionBeansWEB.jar] failed to deploy and has been disabled: [java.lang.IllegalArgumentException: [ejb.CurrencyConvertor] is not an allowed property value type].|#]
Tja… CurrencyConvertor is de local business interface. CurrencyConvertorRemote extends CurrencyConvertor en wordt door de bean geïmplementeerd. Het is mij onduidelijk waarom de web-jar niet werkt. Immers, deze heeft alleen de default testservlet.
Wat is er aan de hand?
Eelco Meuter
@Eelco
Begrijp ik nu goed dat je een @Remote business interface laat extenden van een @Local interface? Dat is volgens mij een verboden operatie. Als je dezelfde functionaliteit zowel local als remote wilt aanbieden dan definieer je een POJI
public interface MyInterface {
public void sayHello(String name);
}
en vervolgens maak je twee “dummy” business interfaces die je daarvan laat extenden:
@Local
public interface MyInterfaceLocal extends MyInterface {
}
en
@Remote
public interface MyInterfaceRemote extends MyInterface {
}
De Bean class laat je vervolgens beide interfaces implementeren:
@Stateless
public class MyBean implements MyInterfaceLocal, MyInterfaceRemote {
…
}
Succes!
Bert
berte
Bedankt voor de suggestie, maar dat had ik al geprobeerd met hetzelfde resultaat. Ik begrijp niet helemaal waarom de gevonden oplossing verboden is. Kan je dit toelichten?
Eelco Meuter
Nee 🙂 dat kan ik helaas niet toelichten.
De specificatie verschaft hier geen duidelijkheid. Het enige dat ik uit de specificatie kan opmaken als het gaat om local en remote is dat er wordt gesteld dat je *by design* besluit om je bean een local of een remote business interface te geven. Er staat zelfs letterlijk dat “hoewel het technisch mogelijk is om zowel local als remote te zijn, dit vrijwel altijd een of/of situatie betreft”.
Verder weten we uit de specificatie en de Javadocs welke de verschillende mogelijkheiden zijn om business interfaces te specificeren bij een bean. (zie slides)
Het probleem dat je beschrijft lijkt me iets te maken te hebben met het moment van dependency injection en dan specifiek die van jouw bean type. Wellicht een simpele gedachte, maar je bent toch niet vergeten om @Stateless of @Stateful boven de bean class te zetten?
Probeer anders eens om de meest eenvoudige situatie werkend te krijgen. Maak alleen een local business interface en een stateless session bean. Als dat werkt, maak je er een remote variant naast enz. Het lijkt me zonde van je tijd om te blijven hangen in een oplossingsrichting die we verdenken dat deze verboden zou kunnen zijn.
berte
Deze oplossing werkt en is ook logisch als je erover nadenkt: BusinessInterfaceLocal extends Remote; bean implements local. Nee, ik was de annotaties niet vergeten, maar wel dat een bean een andere injectie annotatie had… Dat verklaart de illegal argument exception en ik vergeet het nooit meer 🙂 . Bedankt, bert voor je suggesties!
Eelco Meuter
Bert,
1) zou je jouw uitwerking van de lab opdracht ook kunnen posten, zodat we kunnen zien of we het goed hebben gedaan, of dat we het anders/beter kunnen doen??
2) het is mij uit jouw verhaal niet geheel duidelijk geworden hoe je in een servlet een referentie naar een sessionbean kunt krijgen. Is het in het geval van de lab opdrachten nou nodig dat de remote interface wordt gebruikt? In verband met marshalling etc niet echt efficient terwijl we in dezelfde JVM bezig zijn dus zou ik local logischer vinden maar ik krijg het niet voor elkaar om een referentie te krijgen naar de local interface van de currenyconverter of het BackAccount.
Hoe ik het heb opgelost luidt als volgt, deze code heb ik overgenomen uit het boek:
ejb.BackAccount b = null;
try {
Context ctx = new InitialContext(System.getProperties());
b=(ejb.BackAccount)ctx.lookup(“ejb.BackAccountRemote”);
} catch (NamingException e) {
throw new ServletException(e);
}
3) je had het tijdens de eerste avond over een pool van een willekeurig aantal ‘visjes’ van stateless session beans, waarvan er telkens 1 wordt geplukt die de gewenste methods uitvoert. Dat aantal kan 1 zijn, maar ook 100 afhankelijk van de drukte van de server, en de configuratie. Nu heb ik op de currencyconverter interceptors gezet zodat gelogd wordt wanneer een object wordt gecreeerd en wanneer hij ‘de kop om wordt gedraaid’. Ik zie in de uitwerking van beide opdrachten dat er telkens slechts 1 instantie van de converter wordt gemaakt, ik vermoed zelf op basis van een lazy constructie.
Zelfs al ga ik naar mijn “Admin Console” op http://localhost:4848/ en ik stel bij “EJB Container” de setting “Initial and Minimum Pool Size” op 8 “number of beans” in, dan nog wordt er slechts 1 currencyconverter object gemaakt.
Ik had er 8 verwacht. Waar zit mijn denkfout????
Bedankt voor je tijd.
Erwin Kooi
@Erwin
1) Die zal ik nog posten, heb ze zo niet bij de hand.
2) De eenvoudigste manier om een referentie naar een bean te krijgen is:
@EJB CurrencyConverterLocal converter;
of
@EJB CurrencyConverterRemote converter;
De container verzorgt de injection op basis van het type van de business interface.
Ik ben het met je eens dat je kunt discussieren over of het zin heeft om voor dit lab voor remote benadering te kiezen, maar daar gaat het niet zo om. De bedoeling is om je te laten zien dat zowel remote als local toegang mogelijk is en dat het werkt 😉
3) Als je in de admin console naar het Configuration menu gaat en dan naar EJB Container, dan kun je daar inderdaad instellen wat het pooling gedrag is. De instelling die jij noemt (Initial and Minimum Pool Size) kun je bijvoorbeeld op 10 zetten. Vervolgens klik je op de SAVE button rechts bovenaan de pagina en dan herstart je de server. Als je een Interceptor op een SessionBean zet, die in de @PostConstruct iets naar de console schrijft, dan zul je zien dat er daadwerkelijk 10 instances worden gemaakt op het moment dat je bean de eerste keer wordt aangesproken. Bij mij werkt dat. Wellicht ben je vergeten te saven, of heb je de server niet opnieuw gestart?
berte