cialis generique 20mgviagra a parislevitra cialispays viagra vente librecialis 20mg canadakamagra gel 100 mgbuy cialis onlinecanadian cialisviagra du peroucanadian viagracialis prescriptionviagra vente libre franceviagra i doserviagra par correspondancecialis professionalpharmacy viagracialis bas prixviagra au canadaacheter kamagra gelacheter viagra 50mgcialis prix 20mgviagra kaufenachat cialis en pharmacieprix du viagra 50 mgcheap viagraviagra africainlevitra originalacheter du cialis sans ordonnanceacheter du cialiscommander cialisposologie cialisacheter viagratadalafil moins chervente viagra marocviagra parapharmaciecialis 5 milligrams pilulesou se procurer du viagraacheter du cialis en pharmacieviagra maisonfaut il une ordonnance pour du cialisviagra sans ordonnances francecialis 20mg francetadalafil posologievente de cialis en francecommender du cialisprix levitra pharmacieacheter cialis canadacialis en ligne francemedicament cialis 20mgviagra au quebeccialis once a dayviagra genericviagra ukcomment commander du viagratarif du viagraou acheter viagra sans ordonnancecialis femmevardenafil generiquekamagra ukviagra vente libre espagnekamagra softprix du levitra 20mgviagra bleucialis en allemagnecialis generique tadalafilcommande cialiscialis for salegel kamagralevitra 5mg prixprix cialis en francesubstitut au viagraachat cialis en ligneacheter viagra par internetcommander kamagraachat de levitraprix du cialis en pharmacieviagra pharmacieviagra en belgiqueviagra espagneacheter kamagra en franceles generiques du viagraviagra super actifacheter du levitraachat kamagra gelcommander du cialislevitra generique 20mggenerique viagra francecialis ordonnanceorder cialisviagra naturel pour hommegenerique sildenafillevitra sur ordonnancetrouver viagraou acheter du kamagra a parishimalaya viagrapilules viagraviagra internetviagra generiqueviagra usacheter kamagra belgiqueprix du viagracialis tarifsildenafil oral jelly kamagraprix du viagra en pharmacieviagra en lignecialis au meilleur prixvente de viagra en lignecomment acheter du viagra en suisseacheter du viagraviagra meilleur prixvente cialis belgiquecialis prix officielprix cialis 5prix officiel viagrasildenafil citrate tabletsadolescent viagracomprar viagracialis medicamentcialis generique en lignecialis franceacheter generique cialisviagra gratuitviagra franceviagra algerielevitra cherviagra prix au marocviagra au luxembourgkamagra 100mg pas chervend viagragenerique sildenafil citratesildenafil pas cherprix cialis belgiqueviagra generique francecialis original 20mgle viagraduree efficacite levitraprix du cialis au marocou acheter cialis en lignecialis 2 5mgviagra shoplevitra achatviagra doseachat levitra en francetarif cialisprix du cialis 10viagra pas cher parisoral jelly kamagracialis pas cheracheter pilule viagraviagra naturelleviagra 50 prixviagra sur pariskamagra 100mg gelle viagra est il en vente libre en pharmacievente cialis generiqueviagra jeunevente en ligne cialiscialis prix en pharmacieviagra ou achetervente viagra generiqueviagra herbalachat cialis pas chermaroc viagraviagra soft tabs 100mgviagra pharmacie prixcout viagraviagra pour femme faireacheter viagra suisseacheter cialis en belgiqueacheter viagra en lignecialis generique prixprise viagracialis deutschlandviagra canadianmedicament cialis 20trouver du viagra en franceviagra promoprix viagra au marocachat du viagracialis prix 5mgviagra en thailandecialis 20mg tadalafilkamagra oral jelly achetercialis tadalafil prixcialis posologieacheter levitra sans ordonnancevente viagraviagra pour femme en franceacheter du viagra en franceviagra for menkamagra sildenafil citrateacheter kamagra oral jellypeut on acheter du viagra en pharmacie sans ordonnanceprix viagra 50medicament cialisviagra contre indicationscialis en pharmaciepilule bleue viagraviagra prix belgiqueprix cialis francelevitra achetercialis 20mg moins cherou trouver viagraprix cialis en belgiqueviagra chineachat viagracialis 20 mg tadalafilcialis pas cher en franceacheter en ligne viagraou acheter du levitraprix levitra 20mgprix viagra 100mgcialis generique 10cialis en vente libreviagra en vente libreequivalent viagra naturelviagra amsterdamprix boite viagrapharmacie buy cialisviagra linekamagra frle tadalafil cialisou se procurer viagracout du viagraachat kamagraprix levitraviagra effet sur femmeviagra 25 mg prixviagra professionalacheter viagra quebecgenerique cialis cialis 1x20mgle viagra sans ordonnancekamagra bruxellesviagra pour hommeou acheter du viagra en francele viagra pour les jeunesachat kamagra francegenerique viagracialis pharmacie moins chergenerique viagra en franceprix de viagra au marocachat viagra pariscialis 20mg prix pharmacieachat cialis 20mgou acheter du viagra sur internetcitrulline viagraacheter generique viagraviagra en francecommande levitravente de cialis sur internetlevitra quebecachat viagra pour femmecialis 20mg en francele viagra prixkamagra oral jelly uklevitra generique 10mgviagra 20mgprix du cialis 5mgviagra soft tabscialis prix discountviagra free onlineachat kamagra 100achat viagra sans ordonnancevente cialis en suissele viagra pour hommeconcurrent du viagraacheter cialis belgiquegenerique du levitraou commander cialisacheter du viagra en belgiqueviagra buyviagra professionnelviagra prix canadaviagra boiteprix du viagra en pharmacie quebecviagra commanderacheter levitra en ligneviagra generique achetercialis 5 mg comprimcommander cialis en ligneorder viagrasildenafil 100mgachat cialis 5mgcialis pharmacie en lignegenerique cialis 10mgprix en pharmacie du viagracialis vente libreacheter viagra sans ordonnancemedicaments cialisrecherche viagraviagra indienpharmacie cialiscommander tadalafilcialis dosesildenafil 50 mgcialis commandecialis 50mgcomparateur de prix viagracialis for womenviagra petit prixkamagra pas cherkamagra commandecialis suisseviagra prisesuper cialisachat viagra onlineautre que viagraacheter cialis en lignecomment acheter du viagra sans ordonnancevente de cialis sans ordonnancecialis discountou acheter du viagracialis pharmacieviagra de himalayaachat cialis prokamagra oral jelly viagra generiquesite fiable cialisviagra japonviagra en algerieviagra legalviagra pour femme prixviagra masculinou acheter du viagra sans ordonnanceacheter cialis au canadaachat viagra pas cherviagra pour femme au quebecgenerique du viagraprix en pharmacie du cialiscialis pour femmelevitra pharmacieviagra marocprix cialis generiqueacheter du cialis en lignecialis le moins cherkamagra piluleskamagra fastcomparatif prix viagracommander levitrakamagra indeacheter cialis 20tadalafil softcialis 2 mgpharmacie online cialisprix cialis 5mg en pharmaciekamagra oral jelly 10 sachetssildenafil tablets 100mgviagra pour la femmeviagra pharmaprixacheter viagra en espagnevends viagravente viagra parisviagra a montreallevitra prix marocfemme et viagragenerique viagra belgiqueviagra naturel maroccialis montrealprix viagraviagra conditionnementviagra herbepharmacie en ligne levitraacheter en ligne cialiscialis expressviagra en vente libre en franceacheter vardenafilviagra pour jeuneviagra avec ordonnancecialis prix suisseprix viagra en pharmaciecialis commanderou acheter du cialis sur internetcomparateur de prix cialisviagra andorrebuy viagra in canadaou acheter le viagraprix cialis viagratarif levitraviagra posologiecialis 100viagra 18 ansachat de viagra en suissetadalafil pas cheracheter cialis sans ordonnanceachat generique cialiskamagra livraison rapideprix du viagra en pharmacie en francecialis generic canadale cialisvente levitracialis 5mg prix en pharmaciequel est le prix du viagralevitra en pharmacieviagra venteprix cialis pharmacieboite de cialisviagra pour femmeviagra discountvente en ligne viagracialis acheterpromo cialiscialis one daygenerique levitraprix de levitraachat viagra naturelkamagra shople viagra est il en vente libreprix cialis pharmacie parisprix viagra francecomprimes cialisacheter sildenafil 100 milligramscialis moins cher parisachat levitra generiqueacheter viagra generiquetadalafil achatviagra canada onlineachat cialis franceprix cialis marocprix du levitra en baisseacheter viagra paristadalafil 10achat cialis en suissecialis en algerieachat cialis quebecprix cialis 10 mgcontre indication viagracialis prix maroclevitra 20mg generiqueviagra 100mgacheter viagra marocproduit similaire au viagravente viagra canadaacheter viagra canadawoman viagraachat viagra en suisseequivalent du cialiscommander du viagrakamagra moins cherle kamagraviagra himalayaviagra softeffet viagraviagra le moins cherviagra pour femme achata vendre viagrageneric viagra cialisviagra le prixgenerique tadalafilviagra 100vente tadalafilkamagra generiqueviagra 50 ou 100 mgviagra generic canadaachat viagra generiqueprix kamagra oral jellyacheter viagra en ligne en francevente cialis en belgiquecialis 20mg en pharmacieacheter viagra en pharmaciepilule viagracialis 10mg prixkamagra oralacheter kamagra oral jelly en francenatural viagraboite de viagraviagra libreviagra aux plantesmedicament levitraacheter cialis nettadalafil genericviagra 100 prixcialis meilleur prixou avoir du viagrageneric cialis tadalafilcialis fiableprix du cialis 5 mg en pharmaciecialis online canadaprix de cialiscialis 20mgviagra orderacheter viagra femininparapharmacie cialisacheter cialis 5mgbelgique viagrasubstitut viagracommander viagrasachet kamagralevitra baisse de prixsildenafil citrate tablets 100mgcialis naturelviagra canadaacheter du viagra a parisviagra pricecialis generique canadatadalafil 5mgcialis 5mg pas chercialis ukprix kamagraviagra achat en lignecanadian pharmacy cialisle viagra marocainmedicaments levitrakamagra plusviagra prix officielviagra en pharmacieviagra generique en lignele viagra des femmesdosage viagrakamagra pour femmeviagra a quel agele prix du viagra au marocviagra en vente libre en belgiquecialis generique 10mglevitra 5mgviagra au femininviagra thailandekamagra oral jelly belgiquecialis dose quotidienneacheter du tadalafilviagra generique en francecialis en pharmacie sans ordonnancecialis espagnebuy viagra ukacheter viagra en belgiqueviagra femininele viagra des merscomparer prix viagrafaut il une ordonnance pour du viagraacheter cialis pariscialis au marocprix cialis au marocviagra alternativele viagra en tunisiecialis comparatif prixcialis generique softtarif viagraviagra originalcialis dosagekamagra onlineviagra au maroccialis au canadala viagragenerique cialis en franceviagra pas cherviagra en ligne pas cheracheter cialis 10mgviagra pour femmse procurer du viagraacheter viagra au quebecprix viagra belgiquevente cialis en ligneviagra des incascialis traitementcialis internetle viagra naturelcheap generic viagra co ukachat cialis originalgeneric viagrakamagra achatsuper viagraviagra belgique prixviagra femmecialis 10mgviagra en tunisieprix du viagra en pharmacie en belgiquepeut on acheter du viagra sans ordonnanceviagra en parapharmacieviagra et femmedose kamagrasite kamagraprix cialisviagra vente libre belgiquecialis 10mg generiqueposologie du viagraacheter viagra veritabledose cialisou acheter viagraprix cialis 2 5mgacheter viagra montrealviagra tunisieviagra comparatifachat kamagra oral jellyposologie du cialisprescription du viagraachat cialis viagraviagra ordonnanceviagra sans ordonnancesautre que le viagravente de cialis en ligneproduit viagraprix du viagra en francegenerique viagra discountcialis prix de venteviagra efficaceviagra jellyviagra impuissanceviagra dopageacheter cialis ou viagratadalafil soft tablets 20mgachat en ligne cialiskamagra acheterfaut il une ordonnance pour le viagraprescription viagracialis generique 20cialis moins cheronline viagracialis marocviagra generique canadasoft cialislevitra en lignecialis tadalafilcialis en indeviagra online canadacialis 50dosage levitracialis en pharmacie avec ordonnancekamagra soft tabstadalafil generiqueacheter du kamagracheap generic viagrapilule cialiscialis dailyviagra commandeviagra france ordonnancetarifs cialiscialis en andorredu viagraviagra tarifdosage cialisgenerique cialisacheter viagra 50 milligramsviagra en ligne franceachat viagra franceprix viagra en francecialis 10medicament comme viagralevitra canadaviagra pour femme en pharmacieviagra non generiquegenerique cialis 20mgacheter cialis moins cheruk viagraachat cialis en franceviagra marocainacheter cialis au quebecacheter viagra en pharmacie sans ordonnanceviagra aux herbes hornprix levitra lyontarif du levitraarginine et cialisviagra sur le netcialis sur ordonnancegeneriques viagraviagra sous ordonnanceou acheter du cialissite cialispilule levitrakamagra canadaviagra prix en francecialis par internetviagra indiacialis activecialis luxembourgcialis le prixles effets du viagracialis prix canadaacheter tadalafil 20mgachat tadalafilviagra gelcialis authentiqueprix cialis en pharmacieou trouver du viagra sans ordonnancele viagra du tibetviagra 50mg prixprix du cialis en franceacheter du viagra en pharmacie sans ordonnanceachat de cialismedicament tadalafilviagra moins cherbuy kamagracialis 5 mg generiquecialis 20mg achatprix cialis pharmacie francecialis generique indevente de kamagrafille viagravardenafil prixviagra a vendreou acheter cialis generiquesildenafil posologiebaisse de prix levitracialis 20 mgpharmacie en ligne viagraviagra pharmacie belgiqueviagra indeandorre viagratadalafil tabletsacheter du viagra au canadaachat vrai viagraobtenir viagraviagra generique sildenafilviagra generique achatprix viagra 100copie viagraviagra chez les jeunescialis generique discountsur quel site acheter du viagracialis 20mg prix en pharmacieviagra en pharmacie prixacheter viagra internetviagra vente en pharmacieacheter 4 gratuit viagralevitra en suisseachat cialis canadaacheter cialis 5 milligramscomparer prix cialiscialis inefficacelevitra 20mgtadalafil 20mgviagra vertviagra generic onlinedosage du viagrabuy viagra onlinecialis au luxembourgcialis one a dayachat vardenafilacheter kamagra 100mgsildenafil citrate 100mglevitra sans ordonnancesuper kamagraacheter cialis pas cherprix cialis 5mgkamagra 100mgkamagra oral jelly 100mgviagra belgiquecialis livraison expresslevitra generiquekamagra 100mg oral jellylevitra tarifviagra vegaacheter viagra pas cherkamagra suissecialis livraison 24hlevitra 20 prixachat viagra montrealboite cialisviagra usalevitra ordonnancecanadian pharmacy viagraviagra himalayenou trouver du cialisprix levitra 20achat levitrageneric viagra onlinele prix de viagra au marockamagra jellyviagra achetercialis genericpilule bleu viagracialis softviagra generique marocou commander du viagrakamagra discountachat viagra suisseviagra professionelacheter cialis tadalafilviagra online canadian pharmacyacheter cialis en francegeneriques cialisvente de viagra en belgiqueonline viagra nowsildenafil 100autre medicament que le viagraachat de kamagracialis 10 prixcialis 20 prix en pharmaciecialis 40cialis belgiquelevitra commanderacheter viagra belgiqueposologie levitravente viagra sans ordonnanceviagra quebecviagra 50mgpharmacie en ligne cialisordonnance cialistadalafil cialisbuy cialis genericcommander cialis en belgiquele levitraacheter viagra pour femmeprix du cialis 10mgpeut on acheter du viagra sur internetherbal viagrageneric tadalafille tadalafilviagra en vente libre en pharmaciecialis une fois par jourbuy viagra canadaviagra canadian pharmacyafrican viagralevitra en vente libreviagra turcou acheter viagra generiqueprix du vardenafilviagra chez les femmesprix du cialisachat cialis belgiquecialis prix en belgiqueviagra online storepilules cialisbuy viagraacheter viagra en francelevitra maroccialis 5 mgvente libre viagrageneric viagra canadafemme viagramen health kamagratadalafil acheterlivraison rapide de viagracialis mgfaux cialisgeneric cialisvente libre viagra belgiquetadalafil e20levitra professionnelcialis pharmacie parisviagra femininviagra des femmesvardenafil 20alternative au cialiscommander du kamagraviagra naturel pour femmecomment acheter cialisvardenafil 20mgviagra rapideviagra ou autreviagra sans ordonnance belgiquelevitra 20levitra suissekamagra ventecomment acheter du viagra en franceviagra prescriptionviagra en vente libre en suisselevitra femmeprix du levitra en belgiquecialis originalcialis 20mg acheterviagra livraison 48htrouver kamagraacheter cialis en toute securiteviagra pharmacie parisachat cialis sur internetviagra du maroccialis prisekamagra thailandeacheter viagra moins cherou acheter du vrai viagraviagra fillecomment acheter du viagra en pharmacievente viagra belgiqueviagra medicamentcialis prix parislevitra 40 mgprix du cialis en suisseviagra pour femme canadacialis en venteprise du viagrakamagra francegenerique de viagrato buy cialisviagra pharmacie sans ordonnanceviagra generique belgiquejelly kamagraprendre cialisacheter tadalafilcialis gelou acheter le cialisviagra mgpharmacie viagraviagra en herbeachat de cialis sur internetviagra parisprix viagra marocgenuine viagravente kamagraou trouver du viagra a pariscialis sur internetachat cialiscommander cialis pas chercialis prix franceviagra equivalentle viagra peruvienpharmacy cialisviagra livraison discreteacheter viagra originalkamagra co ukachat levitra 20mgcialis prix belgiqueachat viagra en lignecialis generique pas cherprix du tadalafilprix du viagra au maroccialis indienbuy cialis online canadacialis pariscialis pas cher parisacheter du viagra en ligneviagra prix franceacheter viagra au canadaacheter vrai cialisgenerique cialis pas cheracheter du viagra pour femmefemale pink viagrale viagra pour les femmesrecherche cialisviagra achat franceviagra sur internetviagra sur ordonnanceviagra en pharmacitarif cialis 20viagra onlinevente viagra en tunisiekamagra posologiecialis journaliercommande viagracialis chez la femmecialis tunisieachat de viagra en francecommander kamagra oral jellylevitra 10viagra 150prix du cialis 10mg en pharmaciele prix de viagraviagra achat belgiqueachat en ligne viagracomment trouver du viagralevitra au marocachat cialis 20buy generic cialiscommande kamagralevitra posologiecommander cialis 20mgviagra naturel planteacheter cialis quebeccialis prixgeneric levitracialis 40 mgvente cialisposologie viagrabuying viagra onlineviagra 50cialis pas cher toulousevente libre de viagrakamagra 50cialis 20mg prixsildenafil citrateou acheter cialis en francecialis ordonnance ou pasbuy levitracialis prix pharmacievigorex sildenafilacheter du kamagra en francevente de viagrafaux viagraviagra for saleviagra a acheterle prix du levitraprix pharmacie cialisqui prescrit le viagraviagra belgique prescriptionacheter du cialis en belgiqueviagra et ordonnanceorigine viagraequivalent de viagracialis generique belgiqueacheter levitra en franceorder viagra onlinecialis super active 20mglevitra 40acheter cialis 10 milligramsacheter levitra 20mgcialis avec ordonnancecialis buyacheter viagra au marocpharmacy online cialiscialis generique fiablegel viagralevitra 20mg prixou acheter du viagra a parisviagra du tibetviagra ou generiquecialis achat francekamagra jelly 100mgsildenafil femmesildenafil jellyviagra en suissepink viagraacheter kamagracialis tadalafil 20mgou acheter levitrabuy viagra online canadase faire prescrire du viagraboite viagraviagra francaiskamagra sans ordonnanceprix cialis 20 mg comprimacheter du viagra sur internetsildenafil citrate gelviagra chez la femmelevitra dosagepharma cialislevitra medicamentandorre cialisgenerique levitra 10mgcialis 5kamagra oral jellysildenafil generiquecialis ou acheterviagra naturelviagra ou similaireviagra pour les femmesvente viagra francemeilleur prix cialistrouver viagra parisgenerique cialis softkamagra cheapvente viagra en lignecialis super actifcommander cialis canadaou commander viagraacheter cialis sur internetprix du cialis en espagneviagra du nepaleffet kamagra oral jellyviagra faut il une ordonnancesans ordonnance viagrameilleur prix viagracialis 5gviagra hong kongmeilleur site pour acheter cialisacheter levitrapharmacie en ligne kamagravente de levitraposologie tadalafilbuy cialis in canadaequivalent cialiscialis generiqueviagra en anglaisachats cialisprix du viagra 100mgcialis conditionnementlevitra moins chertadalafil prixprix du levitra en pharmacieviagra super activeviagra prix en pharmacieprix du viagra en belgiqueviagra en grande surfaceachat de cialis en lignecialis 20 mg comprimviagra for womencomparateur prix cialisje veux du viagramedicament viagrakamagra marseilleacheter cialis franceviagra pillscialis a vendretarifs viagrakamagra 100pays vente libre viagraviagra au herbebuy viagra online ukcommande de cialisviagra femalevardenafil 10mglivraison rapide cialisou trouver du cialis pas chercialis super activeprix du levitra 10mgbuy levitra discountprix cialis 20mgacheter viagra sur internetviagra pour les jeunescialis indiaviagra en allemagnecialis 20mg le prixacheter du viagra pas chernouveau cialisviagra 100mg prixcialis achatlevitra prix pharmacieprix du sildenafilcommande cialis generiquebaisse prix levitraachat viagra pharmacieviagra bruxellesviagra sur les femmescommander cialis genericpeut on se procurer du viagra sans ordonnancecialis commercialvente de cialisacheter du viagra generiqueprix du cialis 20prise de cialiscialis generique pharmacieachat de viagra en ligneviagra pharmacie ordonnanceou trouver du levitraachat cialis generiquesildenafil 100 pilulesviagra sildenafilachat viagra sur internetviagra womencialis en suisseviagra europeviagra 25mgcommande de viagradelivrance viagrafausse ordonnance viagracialis 20mg pas cherdosage sildenafilviagra en 24hacheter viagra pharmacieequivalent viagra pour femmeparapharmacie viagracheap cialiscialis orderviagra pour femmesmeilleur site viagraprix levitra en pharmaciequel viagra choisirvente cialis 20mgle prix de cialisachats viagracialis 5mgcialis 100mgcialis in franceou peut on se procurer du viagrakamagra belgiqueviagra prix suisseachat cialis en europeachat cialis internetacheter viagra onlineprix cialis 10mg en pharmacievente viagra quebeccomment acheter du cialismedecin viagranouveau viagragenerique du cialisachat cialis acheter cialiscialis generique en belgiquecialis indeacheter viagra franceviagra canada pharmacyviagra expresslevitra 10mgfemale viagradose viagraviagra cheapviagra livraison 24hviagra luxembourgcialis en ligne canadapris du viagratarif du cialiscialis comprimcomparatif prix cialiscialis en lignepeut on acheter viagra sans ordonnancele prix du viagracialis venteprix viagra pharmacieacheter levitra en suisse4 gratuit viagracialis lyonachat viagra en franceachat cialis 10mgacheter du cialis sur internetmedicament generique cialiscialis femininviagra vente libre en pharmacieordonnance pour cialisacheter kamagra franceachat cialis suisseachat viagra en ligne canadavente de viagra sans ordonnancelevitra en belgiqueacheter viagra generique en francecialis usacialis en franceequivalent du viagragenerique de cialistadalafil 20 milligrams 20cialis en belgiquecialis pas cher en pharmaciecialis 20mg andorrekamagra indiakamagra chewable tabletsite viagralevitra prix en baisseviagra naturalviagra gaykamagra 100 chewable tabletcialis jellyviagra en andorreprix medicament cialiscommander cialis en francelevitra 10mg prixcialis 200prix du cialis pharmacieacheter du viagra en pharmacieviagra mauritaniecialis onlinepilule de viagraachat de viagraachat cialis moins cherviagra en indecialis sans ordonnancevente viagra suisseviagra peruviencialis 5mg prix pharmacieprix levitra 10mgviagra authentiquelevitra vardenafildosage du cialislevitra francecialis generique franceprix du levitraacheter sildenafilcialis original livraison rapidekamagra oral jelly pas cherviagra senegalcialis livraison rapideprix du viagra en suisseprix du cialis en belgiqueprise de viagramedicament generique viagraacheter cialis 20mgcommander cialis generiquevente en ligne de cialisachat viagra en belgiquecialis 20mg generiquekamagra oral jelly prixviagra prescription mprix du medicament levitrakamagra sildenafilbuy cialis canadaremboursement viagraobtenir du viagrapilule viagra pour femmecialis 5 milligrams prixcialis 20mg conditionnementviagra pharmacie francecialis 20viagra en europewomen viagrabuy cialiscanada viagraviagra en ligne en francekamagra marocacheter viagra naturelvente viagra en francecialis generique en francegeneric cialis 20mgcommander viagra en ligneou commander kamagraachat viagra quebeccialis pour hommecialis francaissite fiable viagracialis europetadalafil canadacialis angleterrecialis en tunisieviagra livraison expresscialis side effectscanada cialisou acheter cialisviagra vente librelevitra prix en pharmacietadalafil 20achat viagra internetmeilleur site pour acheter du cialisacheter cialis originallevitra en francele prix du cialisgenerique levitra 20pharmacie paris viagrakamagra oral jelly franceprise cialissildenafil citrate 50mgviagra prixequivalent au viagraviagra du pauvretrouver du viagracialis 10mg prix en pharmacietadalafil 10mgcialis sans ordonnance belgiquecialis sans ordonnance en pharmaciecialis avec ou sans ordonnanceacheter levitra generiquelevitra pour femmeordonnance viagraviagra roseviagra en gelle medicament cialiskamagra prixcialis andorreviagra en espagneviagra achatposologie kamagracialis soft tabsviagra echantillon gratuitkamagra sachetgenerique du viagra en pharmacierecette viagracialis effetlevitra 10mg generiqueviagra a vendre montrealvente viagra tunisieprocurer viagracialis 20 generiquelevitra belgiquecialis prix en francecialis vente en francecialis 2 5viagra aux herbespharmacie canadienne cialiscialis achat internetvente en ligne de viagracialis 5mg prixcialis quebeccialis mensuelachat viagra andorreviagra dosageequivalent viagralevitra pas cherventes viagracialis contre indicationblue kamagraprix levitra belgiqueviagra jeune hommeordonnance pour viagraprix de viagralevitra prixle cialis est il en vente librevente libre cialisgeneric cialis 30acheter cialis generiqueprix du cialis 20 en pharmacieachat viagra belgiquevente du viagraviagra livraison rapidekamagra gelviagra suisseviagra pharmacyacheter viagra a montrealcialis 30 mgviagra envoi rapidecialis canadaprix du medicament cialiscomment se procurer du viagra sans ordonnancecialis sans prescriptionviagra moin cherebuy tadalafilacheter cialisviagra par internetlivraison rapide viagratadalafil naturelviagra generique pas cherviagra commercialkamagra pas chere

Configuración y uso de Apache JServ

Ari Halberstadt, 1999 (ari@shore.net)
Traducido por Manel Guerra, 2001 (manel.guerra@wanadoo.es)


Apache JServ es un módulo para el popular servidor web Apache que implementa la API de servlets de Java de Sun para ejecutar codigo del lado del servidor. Puede que esté interesado en este artículo si esta desarrollando software Java para ejecutarlo en un web site y se usa el servidor Apache. Actualmente el servidor Apache es el más popular y utilizado en Internet. Tanto el servidor Apache como el módulo Apache JServ son libres e incluyen su código fuente completo. Este artículo proporciona información sobre cómo usar Apache JServ para desarrollar servlets de Java, incluyendo tanto la instalación básica como configuración y gestión interemedia y avanzada.

Este artículo (o una versión muy parecida) aparece en el libro Professional Java Server Programming, publicado por Wrox Press. Un artículo relacionado, centrado en la configuración de Apache Jserv desde la perspectiva de un administrador de Apache aparece en el libro Professional Apache de Peter Wainwright, también publicado por Wrox Press.

Nota: Los ejemplos de este artículo han sido probados con Apache JServ 1.0b5, que fue la última release beta antes de la versión final 1.0 del 14 de Junio de 1999.

 

Contenido

 

Arquitectura

Los Java servlets deben ser ejecutados desde una máquina virtual Java (JVM de ahora en adelante), y por lo tanto cualquier entorno de ejecución de servlets debe incluir una. Añadir una JVM al servidor Apache no es una opción viable, la complejidad y sobrecarga asociadas a una JVM son prohibitivas, y degradarían la arquitectura del servidor. La solución adoptada con Apache JServ ha sido separar la JVM del servidor Apache.

Esta separación proporciona, además, diversas ventajas. Permite el uso de cualquier JVM compatible proporcionada por cualquier proveedor. No se tiene que hacer ninguna modificación al servidor web cuando se hace un cambio en la JVM, como actualizarla a una versión mejorada. También proporciona mayor estabilidad el separar los procesos, permitiendo así protecciones de proceso y nivel por el sistema operativo. Si la JVM cae o se desconfigura, el servidor web seguira funcionando normalmente. También proporciona funcionalidades avanzadas, como arranque automático versus arranque manual, diferentes JVMs para diferentes configuraciones y la habilidad de soportar balance de carga en sites con un alto tráfico.

El servidor Apache incorpora una arquitectura modular, mediante la que se le pueden añadir funcionalidades. Los módulos pueden ser enlazados con el servidor estáticamente o bien puden ser cargados de forma dinámica usando DSO (objectos dinámicos compartidos, Dinamic Shared Object) en Unix o DLL (Dynamically Linked Libraries) en Windows. La API para estos componentes modulares está basada en el lenguaje C.

Apache JServ está implementado como dos componentes separados, uno escrito en C y el otro en Java, llamado Protocolo Apache Jserv (Apache JServ Protocol-AJP). La versión actual de este protocolo es la 1.1., por lo que le denomina ajpv11.

El lado C de Apache JServ, llamado mod_jserv, proporciona una interficie entre el servidor web Apache y el lado Java. El módulo pasa peticiones e información entre el servidor web y el lado Java, y puede ser usado para arrancar y parar automáticamente la JVM en que el se ejecuta dicho lado Java.

El lado Java de Apache JServ, llamado el Motor de Servets (Servlet Engine), implementa la API servlet, y es donde está la mayoría de las funcionalidades del Apache JServ. El lado Java está, de hecho, completamente separado del lado C, y el único enlace entre ellos es el AJP. Así, se puede atacar el lado Java desde cualquier servidor web siempre que se tenga un módulo apropiado de comunicación usando AJP para ese servidor web.

El lado C, o mod_jserv,se puede entender como un cliente del lado Java del Apache JServ. Del mismo modo, el lado Java se puede entender como un servidor que acepta peticiones desde el cliente. Éste es, esencialmente, un modelo de tres capas, en el que el navegador actúa como front end, el servidor web es la capa media y el lado C del Apache JServ es el back end. Este modelo de tres capas se puede extender a uno de N capas si se accede a servicios adicionales como bases de datos o servidores de aplicaciones a través de Apache JServ. En este modelo, la capa comprendida por servidor web Apache y mod_jserve puede ser reemplazada con cualquier programa que use el protocolo AJP para comunicarse con Apache JServ.

Apache JServ introduce también los conceptos de almacenes (repositories) y de zonas de servlets (servlet zones). Los almacenes de servlets son lugares desde donde son llamados los ficheros de clases de Java, incluyendo ficheros JAR (Java ARchives) y directorios que contengan jerarquias de clases de Java. Las zonas de servlets (servlet zones) son análogas a hosts virtuales en un servidor web. Cada zona puede tener su propio conjunto de servlets, e incluso usar una JVM dedicada. Secciones posteriores detallarán más cómo usar zonas de servlets y almacenes.

 

Instalación básica

Esta sección proporciona una introducción rápida para tener funcionando en una máquina una instalación de Apache y Apache JServ. Se pueden explorar opciones de configuración más avanzadas una vez se haya completado con éxito la instalación básica. Ésta consiste en dos pasos principales: instalación del servidor web Apache, y seguidamente la instalación del motor de servlets Apache Jserv. También se puede añadir Apache JServ a un servidor Apache ya existente saltando la instalación del servidor, haciendo sólo la instalación del Apache JServ.

El ejemplo de instalación proporciona un punto de partida básico para explorar servlets Java usando Apache JServ, pero hay unos cuantos aspectos de una configuración completa que se pueden continuar explorando. Para trabajar con Apache JServ sacándole partido se deberían entender conceptos básicos, que incluyen los diferentes tipos de ficheros de configuración, las zonas de servlets, los almacenes (repositories) de clases, la rellamada automática de clases y cómo añadir servlets. Puede que también quieras explorar temas más avanzados, como mapeo de URLs a servlets, configuración de hosts virtuales, uso de múltiples JVMs, mejora del rendimiento, consideraciones sobre seguridad y funcionalidades añadidas.

 

Requerimientos

Se necesita un sistema con JDK 1.1 o 1.2. También se necesita bajar e instalar el Java Servlet Development Kit (JSDK), versión 2.0, desde el website de Sun: http://java.sun.com/products/servlet/index.html. La versión 1.0 de Apache JServ es comptabile sólo con la versión 2.0 del JSDK, y no funcionará con ninguna otra versión de JSDK.

Para la instalación en un sistema Unix también se necesita un compilador C y la utilidad make, como por ejemplo gcc y gmake del proyecto GNU, disponibles en el web site de Free Software Foundation www.fsf.org. Casi todos los sistems Unix incluyen versiones apropiadas o equivalentes a estos programas en su instalación estándar. Para la instalacion en Windows NT, corriendo sobre un i386 o compatible, no se necesita un compilador de C, ya que estan disponibles directamente los programas de instalación conteniendo los binarios compilados de Apache y Apache Jserv.

Los requerimientos de disco son mínimos, una instalación completa de Apache y Apache JServ en mi sistema Linux (sobre Intel Pentium) ocupa alrededor de 3 MB, y necesita unos 10 MB adicionales para compilar y construir ambos programas. Los requerimientos de memoria dependen, en gran manera, del sistema operativo que se tenga y de la JVM. Como la JVM utilitza la parte del león de los recursos de memoria, se debe consultar la documentación de la JVM propia, aunque una buena aproximación es tener, al menos, 32 o 64 MB disponibles.

Antes de instalar Apache JServ se debería verificar que se tiene una instalación de Java operativa. El intérprete debe ser compatible con JDK 1.1, lo que se puede comprobar con el comando

java -version java version "1.1.7"

Se puede comprobar si se puede compilar código Java simplemente compilando un programa de prueba. Per ejemplo, guardando el siguiento código en un fichero llamado HolaMundo.java:

public class HolaMundo {
public static void main(String argv[])
{
		System.out.println("Hola, mundo!");
}
}

y despues compilando y ejecutando el programa:

javac HolaMundo.java
java HolaMundo
Hola, mundo!

Si no se puede compilar y ejecutar este pograma, deberían consultarse las instrucciones de instalación del JDK.

Para simplificar el desarrollo de servlets, se puede añadir el path del JSDK al classpath, lo que permite que scripts de ejemplo que vienen con Apache JServ puedan localizar automáticamente el JSDK, si no, se tendrá que especificar el path del JSDK cada vez un servlet se compile. Por ejemplo, en Unix, añadiendo las líneas

CLASSPATH=$CLASSPATH:/usr/local/java/jsdk/lib/jsdk.jar
export CLASSPATH

al fichero .profile, en el que /usr/local/java/jsdk es el sitio donde se ha instalado el paquete JSDK de Sun.

Unix

Hay que bajarse, descomprimir, configurar, compilar e instalar el servidor Apache y el motor de servlets Apache JServ. Cada producto incluye suficientes directivas/instrucciones para configurarlo, compilarlo e instalarlo en sus respectivos documentos INSTALL.

La principal decisión a tomar es compilar Apache con DSO o bien enlazar (linkar) Apache JServ estáticamente con el servidor. El soporte DSO permite a Apache llamar módulos en tiempo de ejecución, reduciendo así el volumen del ejecutable y añadiendo y eliminando los modulos más convenientes, pero no todos los sistemas proveen soporte DSO, por lo que, en ese caso, se tiene que usar una compilación estática.

Para tener una referencia, he incluido las instrucciones que usé para hacer una instalación limpia de Apache v1.3.6 y Apache JServ 1.0b5 en mi sistema Red Hat Linux v5.1. He incluido dos versiones de dos grupos de instrucciones: uno compilando Apache con soporte DSO, y otro enlazando las librerías estáticamente. Para otros sistemas, se necesita adaptar estos comandos, y también se debe instalar las versiones más recientes de Apache y Apache JServ. En estos ejemplos, yo he utilizado la utilidad wget (del proyecto GNU) para bajarme las aplicaciones, pero si no está en el sistema propio, se puede utilizar cualquier navegador para bajártelas.

Necesitarás hacer la instalación como un usuario con suficientes privilegios como para escribir en los diferentes directorios, un usuario como por ejemplo root. Sin embargo, puedes instalar los programas en cualquier sitio de tu disco, incluso en tu directorio personal (home), ya que el directorio de instalación se indica usando la directiva --prefijo en el script de configuración de Apache, y con las directivas --with-apache-install o --with-apache-src en el caso del script de Apache JServ.

Apache

Script de ejemplo para instalar el servidor web Apache con soporte DSO:

% cd /usr/local/src
% wget http://www.apache.org/dist/apache_1.3.9.tar.gz
% gunzip -c apache_1.3.9.tar.gz | tar x
% cd apache_1.3.9
% ./configure --prefix=/usr/local/apache 
  --enable-module=most --enable-shared=max 
% make
% make install

Script de ejemplo para instalar el servidor web Apache sin soporte DSO:

% cd /usr/local/src
% wget http://www.apache.org/dist/apache_1.3.9.tar.gz
% gunzip -c apache_1.3.9.tar.gz | tar x
% cd apache_1.3.9
% ./configure --prefix=/usr/local/apache
% make
% make install

Llegados aquí, y suponiendo que no ha habido errores durante la instalación, deberías poder arrancar Apache y confirmar que está trabajando accediento la página por defecto del mismo:

% /usr/local/apache/bin/apachectl start
% lynx http://localhost

Si no puedes acceder a la página por defecto del servidor, entonces deberías mirar en el web site de Apache, http://www.apache.org, y en la documentación on-line para más asistencia.

El procedimiento superior provee una instalación bastante rudimentaria, por lo que deberías refererirte a la documentación on-line de Apache, accesible a través de la página por defecto (http://localhost), para más instrucciones de configuración e instalación (por ejemplo, podrías activar el arranque automático de Apache después de cada rearranque del sistema).

Apache JServ

Script de ejemplo para instalar Apache JServ con soporte DSO:

% cd /usr/local/src
% wget http://java.apache.org/jserv/dist/Apache_JServ_1.0.tar.gz
% gunzip -c Apache_JServ_1.0.tar.gz | tar x
% cd ApacheJServ_1.0
% ./configure --with-apache-install=/usr/local/apache
% make
% make install

Nota: con la versión 1.1 de Apache JServ, usar la opción --with-apache-install dará un error. En vez de eso, debes usar el comando

./configure --with-apxs=/usr/local/apache/bin/apxs

Script de ejemplo para instalar Apache JServ como un módulo estáticamente enlazado (este script construye y reinstala Apache despue de construir e instalar Apache JServ):

% cd /usr/local/src
% wget http://java.apache.org/jserv/dist/Apache-JServ-1.0b5.tar.gz
% gunzip -c Apache-JServ-1.0b5.tar.gz | tar x
% cd ApacheJServ-1.0b5
% ./configure --with-apache-src=/usr/local/src/apache_1.3.9 
  --enable-apache-conf
% make
% make install
% /usr/local/apache/bin/apachectl stop
% cd /usr/local/src/apache_1.3.9
% make
% make install

Una vez instalado Apache JServ aún hay que configurar Apache para que se comunique con Apache JServ, lo que se puede hacer añadiendo la siguiente línea al final del fichero httpd.conf file (en /usr/local/apache/conf/httpd.conf):

Include /usr/local/src/ApacheJServ-1.0b5/example/jserv.conf

Asumiendo que la instalación haya procedido sin errores, deberías poder rearrancar Apache y acceder al servlet de ejemplo Hello, para confirmar que tu instalación haya sido correcta.

/usr/local/apache/bin/apachectl restart

(espera unos segundos para darle tiempo a Apache a rearrancar)

lynx http://localhost/example/Hello

Si no puedes acceder al servlet, entonces mira en la sección de solución de problemas. Prueba a acceder la URL unas cuantas veces, ya que puede ser que Apache JServ tarde algunos segundos en cargarse y empezar a aceptar peticiones.

Windows

Instalar Apache consiste en bajarse y ejecutar el programa instalador y luego arrancar Apache. Se puede bajar el instalador para Windows desde http://www.apache.org/dist (para Apache 1.3.6 els instalador está en el fichero apache_1_3_6_win32.exe). Después de bajarte el fichero, ejecuta el instalador (haz doble click sobre el fichero .exe). Después de la instalación, arranca Apache desde el grupo de opciones de menú Apache Web Server, bajo el menú de Inicio desde el prompt de sistema (línea de comandos). Hecho esto, usa tu navegador para acceder a la home page por defecto en http://localhost. Si eso no funciona, consulta la documentación de Apache y el web site de Apache.

Instalar Apache JServ consiste en bajarse y ejecutar el instalador, y luego rearrancar Apache. El instalador para Windows de Apache JServ está en http://java.apache.org/jserv/dist/. Para Apache JServ 1.0b5 el instalador está en el fichero Apache-JServ-1.0b5.exe. Después de bajarte el fichero, ejecuta el instalador (haz doble click sobre el fichero .exe), seleccionando la instalación integrada, de manera que Apache JServ será arrancado y parado automáticamente por el servidor web. Después de la instalación rearranca el servidor web (o sea, para y arranca el servidor).

Para probar la instalación, accede a la URL http://localhost/servlets/IsItWorking, que debería ejecutar el servlet de ejemplo y mostrar una página simple. Si no puedes acceder al servlet, mira en la sección solución de problemas. Prueba a acceder la URL unas cuantas veces, ya que puede ser que Apache JServ tarde algunos segundos en cargarse y empezar a aceptar peticiones.

 

Ficheros de configuración y directivas

Apache y Apache JServ utilizan diversos ficheros de configuración. Respecto a Apache, el fichero más interesante es httpd.conf, donde estan (entre otras cosas) las directivas para la carga de módulos y la configuración del módulo mod_jserv.

El fichero de configuración principal para el motor de servlets es el fichero de propiedades del motor, y suele ser jserv.properties. Contiene las propiedades pasadas a la JVM, opciones diversas y preferencias de seguridad, y una lista de todas las zonas de servlets y sus ficheros de propiedades respectivos.

Cada zona de servlets usa también su propio fichero de propiedades, el fichero de propiedades de zona. Éste contiene propiedades que especifican almacenes (repositories) desde los que los servlets son llamados en la zona, si las clases son cargadas automaticamente cuando se cambian, y otros puntos especificos de cada zona de servlets

Directivas de Apache

Si has instalado la configuración de Apache JServ, entonces habrás añadido una directiva Include en httpd.conf para añadir el fichero de configuración de ejemplo (estas directivas se usan para configurar mod_jserv de manera que se pueda comunicar con el motor de servlets). También puedes configurar mod_jserv añadiendo las directivas apropiadas en httpd.conf.

Si estás usando Apache JServ como un módulo DSO, entonces deberías incluir una directiva LoadModule en httpd.conf para cargar mod_jserv. En Unix, esto se hace más o menos como sigue:

LoadModule jserv_module libexec/mod_jserv.so

En Windows, esto sería:

LoadModule jserv_module modules/ApacheModuleJServ.dll

La directiva LoadModule es parte de mod_so, y no deberías utilitzarla si has enlazado mod_jserv estaticament a Apache.

Las directivas que son especificas de mod_jserv estan mejor puestas dentro de una directiva IfModule, de manera que el servidor web pueda arrancar incluso si mod_jserv se elimina de manera temporal. Por ejemplo, una instalación básica podría incluir las siguientes directivas en httpd.conf:

<IfModule mod_jserv.c>
ApJServProperties /usr/local/apache/conf/jserv.properties
ApJServLogFile /usr/local/apache/logs/mod_jserv.log
ApJServSecretKey DISABLED
ApJServMount /servlets /servlets
<Location /status/jserv/>
SetHandler jserv-status
order deny,allow
deny from all
allow from localhost
</Location>
</IfModule>

Los comentarios en el fichero de configuración de ejemplo incluido en Apache JServ (bajo el directorio examples/jserv.conf) incluyen una descripción de todas las directivas de configuración disponibles. Actualmente este fichero se incluye en httpd.conf (a través de la directiva Include de Apache), después de una correcta instalación de Apache JServ. El fichero httpd.conf se carga sólo cuando el servidor web arranca, de manera que tendrás que rearrancar el servidor después de cualquier modificación.

Propiedades del motor

El fichero de propiedades del motor es leído tanto por mod_jserv como por el propio motor de servlets. Este fichero contiene pares de propiedades nombre/valor. Un fichero de ejemplo, que contiene comentarios explicando cada propiedad, se incluye con la distribución de código de Apache JServ en examples/jserv.properties.

Hay un fichero de propiedades distinto para cada JVM usada por Apache JServ. Este fichero contiene propiedades que se necesitan para lanzar la JVM, questiones de de seguridad y comunicación para comunicación con el servidor web Apache, y propiedades para activar rastreo (logging). Este fichero se llama sólo una vez en el arranque, por lo que cualquier cambio sólo será efectivo a partir de la reinicialización del servidor web y la JVM.

A continuación hay un ejemplo de un fichero de configuración mínimo de un motor:

wrapper.bin=/usr/local/java/jdk/bin/java
wrapper.class=org.apache.jserv.JServ
wrapper.classpath=/usr/local/jserv/lib/ApacheJServ.jar
wrapper.classpath=/usr/local/java/jsdk/lib/jsdk.jar
port=8007
security.allowedAddresses=127.0.0.1
security.authentication=false
zones=servlets
servlets.properties=/usr/local/apache/conf/servlets.properties

En este ejemplo, las propiedades wrapper son usadas por mod_jserv para arrancar automáticamente el motor de servlets. La propiedad port indica qué puerto debe usar el motor para comunicarse con mod_jserv, y la propiedad zones lista las zonas de servlets a las que se puede acceder. La propiedad que empieza conel nombre de una zona de servlets, seguida por el texto ".properties" (en el ejemplo, servlets.properties) especifica la localización del fichero de propiedades de zona para cada zona de servlets.

Propiedades de zona

Cada zona de servlets usa un fichero de propiedades de zona. Este fichero contiene una lista de almacenes (repositories) que contienen ficheros de clase y servlets Java. También contiene alias y arguments de inicialización para los servlets de cada zona.

A continuación hay un ejemplo de un fichero de configuración mínimo de propiedades de una zona.

repositories=/usr/local/apache/servlets

Este fichero de propiedades sólo indica un directorio que puede contener servlets.

 

Añadir y ejecutar Servlets

Los servlets se añaden a una zona de servlets poniendo los ficheros compilados de la clase (.class) en uno de los almacenes de la zona. Por ejemplo, se puede añadir un serlvet a la zona de ejemplo de servlets que viene con la instalacin de Apache JServ poniendo el servlet compilado (.class) en el directorio de ejemplo, que esta en la carpeta exampe en la distribución fuente (p.e., /usr/local/src/ApacheJServ-1.0b5/example).

Un buen servlet de ejemplo es SnoopServlet, que se incluye con el JSDK de Sun. Este servlet imprime la mayoría de la información que el motor de servlets le pasa al servlet. Puedes compilar SnoopServlet, lo que da una fichero llamado SnoopServlet.class, que luego tendrá que copiar al almacen de tu zona de servlets. Si estas usando la zona de servlets de ejemplo, deberías copiar el fichero de la clase compilada a /usr/local/src/ApacheJServ-1.0b5/example.

Para ejecutar SnoopServlet, entra su URL en tu navegador:

http://dominio:puerto/example/SnoopServlet

Donde dominio es el nombre de tu dominio y puerto es el puerto por el que se accede a tu servidor web (usualmente es el 80). La forma general de acceder a un servlet es

protocolo://host:puerto/zona/nombre

Donde protocolo es usualmente http, host es la dirección IP o el nombre de tu servidor, puerto es el puerto para conectar al servidor, zona es el punto de montaje de una zona de servlets, y nombre es el nombre completo del servlet o un alias en la zona especificada.

Un error común entre los que empiezan es intentar acceder a un servlet a través del AJP. AJP es sólo para comunicación interna entre el servidor web y Apache JServ, nunca se usa para acceder al servidor web. Así, no pruebes un URL como ajpv11://tudominio:8007/example/SnoopServlet, ya que no funcionará. Accede siempre a tus servlets usando un protocolo estándar como HTTP.

Los servlets cuyas clases estan en un package se acceden a través de su nombre completo de clase. Por ejemplo, si añades un servlet llamado FooServlet en el paquete com.dominio.foo a una zona de servlets cuyo punto de montaje es /servlets, entonces deberías acceder a ese servlet mediante la URL

http://dominio.com/servlets/com.dominio.foo.FooServlet

Puedes ocultar el nombre del servlet y el paquete en la URL definiendo un alias para tu servlet. Esta definición del alias dentro de un almacén de servlets se hace mediante la propiedad servlet.name.code, donde name es el alias que quieres assiganr a tu servlet. Por ejemplo, para definir un alias foo para la clase com.dominio.foo.FooServlet, tienes que añadir la siguiente propiedad al fichero de propiedades de la zona:

servlet.foo.code=com.dominio.foo.FooServlet

Y para acceder al servlet hay que usar el URL

http://dominio.com/servlets/foo

Algunos servlets pueden necesitar información adicional, que se les pasa en el momento del arranque. Se puede pasar cualquier numero de argumentos a un servlet usando las propiedades initArgs en el fichero de propiedades de la zona, y se puede acceder a los argumentos usando el método getInitParameter de javax.servlet.ServletConfig. Por ejemplo, para pasar argumentos de inicialización a FooServlet,

servlet.foo.initArgs=name=This is foo servlet
servlet.foo.initArgs=purpose=Nothing in particular

El formato de esta directiva es servlet.nombre.initArgs, donde nombre puede ser o bien un alias de un servlet o bien el nombre completo de la clase del servlet.

Si tienes demasiados argumentos de inicialización para un servlet, quizás querrás guardarlos en un fichero separado. Esto puedes hacerlo omitiendo cualquier directiva initArgs en el fichero de propiedades de la zona y proporcionando, en cambio, un fichero <nombre>.initArgs en el mismo directorio que contiene la clase del servlet.

La propiedad especial servlets.default.initArgs permite definir argumentos de inicialización que se pasan a todos los servlets. Por ejemplo, le puedes pasar la dirección e-mail de tu webmaster a todos tus servlets, de manera que incluyan la dirección en los mensajes de error generados por ellos.

Normalmente, los serlvets son cargados en la memoria la primera vez que son llamados, de manera que si nadie llama nunca (accede) a un servlet, éste nunca será cargado en la memoria. Sin embargo, podrías querer que determinados servlets se ejecutaran cuando el servidor web (o la JVM) se arrancara. Para esto se usa la directiva servlets.startup, a la que se le proporciona una lista de servlets que seran ejecutados cuando la JVM se arranque. Se pueden añadir servlets a la lista s tienes servlets que hagan procesos en backgroundm, o servlets que tardan algunos segundos en arrancar y no quieres que tus usuarios tengan que esperar un retraso mínimamente notable.

 

Rutas (path) y rellamada de clases

La ruta de clases es donde la JVM busca las definiciones de clases. La ruta de clases en Apache JServ se divide en una ruta de clases de sistema y en un conjunto de rutas de clases de zonas de servlets. La ruta de clases de sistema está compartida entre todos los servlets, mientras que la ruta de clases de las zonas de servlets es accesible sólo desde cada zona.

La ruta de clases de sistema se define de dos maneras: de modo automática, usando la directiva wrapper.classpath en el fichero de propiedades del motor, o de modo manual, donde es cualquier cosa que se le pase al runtime de Java mediante la variable de entorno CLASSPATH o la opcion -classpath.

Cada zona de servlets tiene asignado su propio cargador de clases. Éste es responsable de cargar las definiciones de clase desde los almacenes a la JVM y de detectar modificaciones en los almacenes de clases. Así, si tenemos dos zonas, A y B, y cada una de ellas usa la clase C del almacén R, entonces tendremos dos copias de la clase C, cada una de las cuales es inaccesible a la otra. De la misma manera, cualquier objeto que sea una instancia de la clase C será inaccesible a otras zonas. No importa que el almacén sea el mismo fichero o el mismo directorio, ya que cada uno tiene se cargador separado.

Una característica útil para desarrollar servlets es la habilidad para rellamar clases automáticamente cuando se modifican. Apache JServ recargará las clases si un almacen que contiene una de ellas ha sido modificado, y una zona de servlets también será recargada si su fichero de propiedades se modifica; esto permite instalar y probar nuevas versiones de servlets sin tener que rearrancar el servidor.

Las clases de la lista de una zona de servlets sólo son accesibles a esa zona. Además, sólo las clases cargadas desde un almacén de zona están sujetas a recarga automática si el almacén de zona o el fichero de propiedades cambian. Esto permite poner las clases más usadas y/o las más estables en la ruta de clase del sistema, dando así acceso a clases compartidas y mejorando el rendimiento en general. Por ejemplo, las clases del JDK y del JSDK deberían ponerse en la ruta de clase del sistema (CLASSPATH,-classpath). Así, una libreria estable y comunmente usada, como un driver JDBC, podría ponerse en la ruta de clases del sistema.

La rellamada automática de clases reduce el rendimiento porque se debe comprobar cada almacén en cada una de las ejecuciones de un servlet. La rellamada está activada por defecto, pero se puede desactivar para una zona particular poniendo la propiedad autoreload en el fichero de propiedades de la zona como falsa (false). Esto puede conducir a una mejora significativa del rendimiento, a costa de un ciclo de desarrollo más pesado, ya que se requeriría entonces rearrancar el servidor cada vez que se modifica una classe.

Otro problema de rendimiento de la rellamada de clases es que incluso un pequeño cambio en una clase forzará a una recarga de toda la zona. Esto no suele ser un problema si solo hay unas pocas clases, pero puede ser un problema de rendimiento significativo si hay varios almacenes grandes. Esto se puede esquivar moviendo los almacenes grandes a la ruta de clases del sistema; aunque se perderán los beneficios de la rellamada automática de clases para estos almacenes, se ganará la ventaja un cicle de actualización y pruebas más rápido en las clases con las que se trabaja.

Cuando una zona de servlets se recarga, todos los objetos creados en la zona son destruidos. Con la recarga automàtica activada, incluso el más pequeño cambio en el fichero de propiedades de zona o de uno de los almacenes en una zona causarán la recarga de esa zona, lo que puede ser un problema si se mantienen los estados entre las ejecuciones de un servlet. Por ejemplo, si se mantiene una sesión de un usuario en memoria, se perderá cuando la zona sea recargada. En este caso, la recarga automática no es más que un caso especial del problema, más general, de mantener un estado persistente en un servlet.

La mejor solución para mentener los datos de una sesión es proporcionar un mecanismo persistente: antes que Apache JServ destruya una zona de servlets, llama al método destroy() de cada servlet. Los servlets pueden, entonces, guardar los datos en un almacén persistente, como un fichero o una base de datos. Cuando los servlets son rellamados, sus métodos init() pueden leer la información guardada de la sesión. También se pueden guardar las sesiones siempre que se actualizen, previniendo así pérdidas de datos debidas a errores inesperados (e imprevisibiles, muchas veces: Caída de la JVM, fallos de tensión, etc.)

El acceso a métodos implementados via Java Native Interface (JNI) debe ser provisto por las clases a través del cargador de clases de sistema en la ruta de clases de sistema. Esto es una limitación impuesta por la manera en que los cargadores de clases de Java están implementados, que sólo permiten al llamador de clases del sistema cargar métodos JNI. Dicho de otra manera, no se puede acceder a métodos JNI en clases llamadas a través de la ruta de clases de una zona de servlets, pero se pueden listar esas clases en la ruta de clase del sistema...

 

Añadir zonas de servlets

Apache JServ ejecuta todos los servlets en zonas de servlets, y puede ser configrado con una o más zonas de servlets. A cada zona se le asigna un único punto de montaje y un nombre. El punto de montaje corresponde a una prefijo URL único, de manera que todos los URL que empiezen por ese prefijo (por ese punto de montaje) serán manejados por un servlet de la zona especificada. Por ejemplo, la instalación por defecto incluye una sola zona llamada example, los URL cuyo path empiece con /example seran manejados por el servlet de la zona example.

El disponer de múltiples zonas de servlets proporciona diversas ventajas: las zonas permitan separar servlets por criteros de seguridad, para ejecutar múltiples JVMs, para soporte de de múltiples hosts virtuales, etc. Cada zona de servlets requiere una directiva ApJServMount en el fichero httpd.conf de Apache, una entrada en el fichero de propiedades del motor (compartido) y un fichero de propiedades propio de la zona.

La directiva ApJServMount indica a mod_jserv cómo mapear URLs a zonas de servlets. La sintaxis de la directiva es

ApJServMount ruta protocolo://host:puerto/zona

Donde ruta es la parte principal del URL que se mapea a la zona, protocolo el protocolo de comunicación interno AJP, host es la direción IP o el nombre del host en el que se ejecuta la JVM, puerto es el puerto por el que se comunicará internamente con Apache JServ, y zona es el nombre de una zona de servlets. Ruta y zona són obligatorios. Si se omite protocolo, se entenderá por defecto el valor de la directiva ApJServDefaultProtocol o ajpv11 en Apache JServv1.0. Si se omite host, se entenderá por defecto el valor de la directiva ApJServDefaultHost o el localhost de defecto. Y si se omite puerto, se entenderá por defecto el valor de la directiva ApJServDefaultPort o bien 8007.

Por ejemplo, para mapear peticiones de la ruta /dev/servlets a la zona devservlets en la máquina local, se podría usar la directiva

ApJServMount /dev/servlets /devservlets

Las peticiones a cualquier URL que empieze por /dev/servlets serán manejadas por los servlets de la zona devservlets. En el fichero de propiedades del motor, habrá que añadir una entrada para la zona listandola en la propiedad zones y proporcionando la ruta al fichero de propiedades de la zona. Por ejemplo,

zones=devservlets
devservlets.properties=/usr/local/apache/conf/devservlets.pro
perties

El fichero de propiedades para la zona devservlets debe contener como mínimo una entrada repositories especificando un almacén del cual se llamarán los servlets, por ejemplo:

repositories=/usr/local/apache/devservlets

En este ejemplo, el almacén es un directorio en el cual se pueden poner servlets. Por supesto, hay que crear el diretorio:

mkdir /usr/local/apache/devservlets

Una vez se haya finalizado la configuración de la zona, hay que rearrancar el servidor web. Para el ejemplo superior, se puede usar una URL como

http://tudominio/dev/servlets/MiServlet?address=foo@bar.com

que ejecutará el servlet MiServlet en la zona devservlets.

 

Mapeo de URLs

Hay un par de maneras de mapear URLs, además de las zonas de servlets y los alias. El módulo mod_jserv puede mapear ficheros que acaben en un sufijo particular a un servlet de manera que, cuando el servlet se ejecuta, la ruta al fichero se pasa como información extra al servlet. La otra manera us usar el muy flexible módulo mod_rewrite, que se proporciona con Apache.

La directiva ApJServAction el servlet que se ejecutará para ficheros que acaben en un sufijo determinado. La ruta al fichero solicitado se pasa al servlet, y éste puede acceder a ella mediante los métodos getPathInfo o getPathTranslated de javax.servlet.HttpServletRequest. Por ejemplo, el proyecto Java Apache proporciona el servlet Apache JSSI, que incluye la salida de otro servlet en un fichero HTML. Para mapear ficheros acabados en el sufijo .jhtml al servlet Apache JSSI, hay que añadir una línea como la siguiente en el fichero httpd.conf:

ApJServAction .jhtml /servlets/org.apache.servlet.ssi.SSI

Después de un rearranque del servidor, y asumiendo que el servlet Apache JSSI está instalado, cualquier fichero acabado en .jhtml será analizado por dicho servlet.

Hay veces en que no se quiere que los usuarios vean una ruta como /dev/servlets/MiServlet al acceder al sitio. Alternativamente, también podría interesar 'envolver' ficheros existentes en un servlet para proporcionar autenticación o contenido dinámico. Apache incluye un módulo muy flexible, llamado mod_rewrite, que se puede usar para modificar URL de casi cualquier manera que pueda ocurrirse.

Usar mod_rewrite con mod_jserv es como usar mod_rewrite con cualquier otor módulo o URL. Para los detalles, se debería consultar documentación y ejemplos proporcionados por el autor del módulo, Ralf S. Engelschall, que están incluidos en la distribución de Apache.

Lo único importante que hay que recorder es que la directiva AddModule de mod_jserv debe estar antes de la directiva AddModule de mod_rewrite. Por ejemplo, en httpd.conf,

ClearModuleList
...
AddModule mod_jserv.c
AddModule mod_rewrite.c

Esto es así porque los módulos se ejecutan en la dirección inversa en que se especifican con la directiva AddModule, y mod_rewrite debe ejecutarse antes de mod_jserv.

El resto de esta sección incluye algunos consejos simples para usar mod_rewrite con mod_jserv.

El ejemplo siguiente reescribe cualquier URL que empiece por /auth con /servlets/AuthServlet. La opción [PT] indica a mod_rewrite que debe pasar la URL reescrite para procesos posteriores en Apache.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/auth(.*)  /servlets/AuthServlet$1 [PT]
</IfModule>

Se puede decidir añadir contenido dinámico a una páginas estáticas añadiendo, por ejemplo, el servlet Apache JSSI, que proporciona funcionalidades de server-side include a los servlets Java. Asumiremos que se a añadido previamente una directiva ApJServAction de manera que los ficheros cuyo sufijo sea .jhtml iran a través del servlet Apache JSSI. Si se quiere obtener algún beneficio de esta nueva funcionalidad en los ficheros existentes, pero éstos no se pueden renombrar sin romper URLs ya existentes, y no se quiere mantener una lista de todos los mapeos de ficheros .html existentes a .jhtml, se puede usar la directiva RewriteMap de mod_rewrite y un pequeño programa en Perl para solucionar el problema:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteMap suffixmap prg:/usr/local/apache/conf/suffixmap
RewriteRule ^(.*)\\.html% $1.${suffixmap:$1|html}
</IfModule>

Este ejemplo pasa cualquier URL acabado en .html al programa /usr/local/bin/suffixmap. El programa de mapeo de sufijos devuelve un nuevo sufjio o bien un string NULL para usar el sufijo por defecto.

El código fuente del programa de mapeo de sufijos es:

#!/usr/bin/perl
# Usado para el mapeo de urls con mod_rewrite
$| = 1;
$root = "/usr/local/apache/htdocs";
@suffixes = ("jhtml");
MATCH:
while (<>) {
chop;
$file = $root . $_;
foreach $suffix (@suffixes) {
if (-f "$file.$suffix") {
	print "$suffix\\n";
	next MATCH;
}
}
print "NULL\\n";
}

Este script concatena el directorio raiz de documentos del servidor con la URL proporcionada, y luego comprueba la existencia de un fichero con uno de los sufijos buscados (se pueden añadir fácilmente sufijos adicionales). Si se encuentra una coincidencia, el script devuelve el sufijo de la coincidencia a mod_rewrite escribiendo en la salida estandar, y si no escribe NULL para indicar ue el sufijo por defecto es el que debe usarse. Esta solución no es la aproximación más eficiente, dado que requiere una búsqueda en todos y cada uno de los URLS que acaben en .html. Sería mejor generar manual o automáticamente un texto o un fichero DBM que mapeara URL específicos. Sin embargo, el script anterior es conveniente para usarlo durante el desarrollo y demuestra algunas de las capacidades y flexibilidad de mod_rewrite.

 

Hosts virtuales

Los hosts virtuales son una acertada manera de hacer que un sólo servidor web pueda manejar peticiones para múltiples dominios. Cada host virtual puede tener configuraciones separadas de Apache JServ, mientras diferentes directivas compartidas pueden situarse fuera de la configuración de cualquier host virtual. Las directivas compartidas incluyen las directivas para las propiedades y los ficheros de log (registro) y la URL de estado. Otras directivas, como los puntos de montaje de los servlets y las zonas, se pueden especificar separadamente para cada host virtual.

El ejemplo siguiente muestra una configuración de muestra para dos hosts virtuales, llamados vhost1 and vhost2.

# directivas compartidas
LoadModule jserv_module libexec/mod_jserv.so
<IfModule mod_jserv.c>
ApJServProperties /usr/local/apache/conf/jserv.properties
ApJServLogFile /usr/local/apache/logs/mod_jserv_log
ApJServSecretKey DISABLED
<Location /status/jserv/>
 SetHandler jserv-status
 order deny,allow
 deny from all
 allow from localhost
</Location>
</IfModule>
NameVirtualHost 192.168.1.1

# directivas para vhost1
<VirtualHost 192.168.1.1>
ServerName vhost1.com
DocumentRoot /usr/local/hosts/vhost1/htdocs
<Directory /usr/local/hosts/vhost1/htdocs>
order allow,deny
allow from all
</Directory>
<IfModule mod_jserv.c>
ApJServDefaultHost vhost1.com
ApJServMount /servlets ajpv11://vhost1.com/vhost1
</IfModule>
</VirtualHost>

# directivas para vhost2
<VirtualHost 192.168.1.1>
ServerName vhost2.com
DocumentRoot /usr/local/hosts/vhost2/htdocs
<Directory /usr/local/hosts/vhost2/htdocs>
order allow,deny
allow from all
</Directory>
<IfModule mod_jserv.c>
ApJServDefaultHost vhost2.com
ApJServMount /servlets ajpv11://vhost2.com/vhost2
</IfModule>
</VirtualHost>

Para este ejempo se ha usado una dirección IP sin sentido en la red. La directiva ApJServDefaultHost se necesita porque ambos hosts virtuales comparten la misma direccion IP, y permita a Apache JServ dirigir cada petición a la zona de servlets correcta.

Se necesitará crear los directorios htdocs para cada host virtual, y también los directorios donde almacenar los servlets:

mkdir -p /usr/local/hosts/vhost1/htdocs
mkdir -p /usr/local/hosts/vhost2/htdocs
mkdir -p /usr/local/hosts/vhost1/servlets
mkdir -p /usr/local/hosts/vhost2/servlets

El fichero de propiedades del motor debería contener propiedades tanto para vhost1 como para vhost2 y permitir el acceso desde la dirección IP del host virtual:

wrapper.bin=/usr/local/java/jdk/bin/java
wrapper.class=org.apache.jserv.JServ
wrapper.classpath=/usr/local/jserv/lib/ApacheJServ.jar
wrapper.classpath=/usr/local/java/jsdk/lib/jsdk.jar
port=8007
security.allowedAddresses=192.168.1.1
security.authentication=false
zones=vhost1,vhost2
vhost1.properties=/usr/local/apache/conf/vhost1.properties
vhost2.properties=/usr/local/apache/conf/vhost2.properties

Cada zona necesita también el correspondiente fichero de propiedades de la zona, vhost1.properties and vhost2.properties, que son como cualquier otro fichero de propiedades de zona. El fichero vhost1.properties podria ser como lo que sigue:

repositories=/usr/local/hosts/vhost1/servlets

Se pueden añadir almacenes e indicaciones como para cualquier otra zona de servlets. Y se tiene que crear un fichero similar para vhost2.

A partir de la configuración anterior, peticiones de URLs como http://vhost1.com/servlets/... serán manejadas por la zona de servlets vhost1, mientras peticiones de URLs como http://vhost2.com/servlets/... lo serán por la zona de servlets vhost2.

Con la directiva ApJServMountCopy se pueden hacer zonas de servlets compartidas, accesibles por cada host virtual. Se puede usar esta directiva para proporcionar un conjunto común de servlets básicos para cada host virtual. Permitiendo la copia del montaje, las zonas definidas fuera de cualquier sección del host virtual son automáticamente accesibles para cada host virtual. Si las siguientes directivas se añaden a la parte compartida de la configuración de ejemplo del host virtual, entonces tanto vhost1 como vhost2 tendrán acceso a la zona /share.

ApJServMountCopy on
ApJServMount /share/servlets /share

También se necesitará añadir un fichero de propiedades de zona y una entrada en el fichero de propiedades del motor para la zona de servlets compartida (sólo hay que seguir el mismo procedimiento que para cualquier otra zona de servlets). Así, dado un servlet MailServlet en la zona share, URLs como http://vhost1.com/share/servlets/MailServlet y http://vhost2.com/share/servlets/MailServlet ejecutarían la misma instancia de MailServlet.

 

Ejecutar Apache JServ

Apache JServ se puede usar de dos modos, automático y manual. El modo automático es el mas conveniente para ejecutarlo, ya que maneja el arranque y parada de la JVM. El modo automático es apropiado para instalaciones básicas que utilizan una única JVM. En el modo manual, se debe lanzar la JVM usando un programa externo, como un shell script o un fichero batch. El modo manual da un trabajo extra de configuración, pero permite utilizar cualquier número de JVMs para, por ejemplo, proporcionar aislamiento entre cliente o para dar equilibrar el balance de la carga o la tolerancia a errores.

En el modo automático, el módulo mod_jserv lanza automáticamente la JVM. El módulo tambien monitoriza la JVM y la relanza si ésta finaliza inesperadamente. Cuando el servidor Apache se rearranca o se para, el módulo rearranca o para la JVM. Todo lo que se necesita para configurar el modo automática es usar el valor "off" en la directiva ApJServManual en httpd.conf y configurar adecuadamente las propiedades wrapper en el fichero de propiedades del motor.

El modo manual se requiere, en cambio, si se quiere hacer uso de más de una JVM, por ejemplo, un ISP que proporciona hosting virtual a sus clientes querrá proporcionar a cada cliente una JVM propia para asegurarse que los datos y ejecutables de cada uno de ellos se separan de los del resto. En sitios con alto tráfico también se pueden usar las características de balance de carga añadidads en Apache JServ 1.0b5.

En el modo manual hay que lanzar la JVM. Esto se puede hacer directamente desde la línea de comandos, usando un shell script o un batch script, desde un script ejecutado en el arranque del servidor, etc. A continuación hay un ejemplo de un shell script de Unix que se puede usar para lanzar Apache JServ en modo manual (antes de usar el script, habrá que ajustar las rutas (paths) para las localizaciones de los ficheros en el propio sistema).

Shell script de Unix para lanzar Apache JServ en modo manual

#!/bin/sh
properties=/usr/local/apache/conf/jserv.properties
log=/usr/local/apache/logs/jserv_manual.log
CLASSPATH=$CLASSPATH:/usr/local/jsdk/lib/jsdk.jar
CLASSPATH=$CLASSPATH:/usr/local/jserv/lib/ApacheJServ.jar
java org.apache.jserv.JServ $properties $1 2>> $log

Cuando se ejecuta en modo manual, el error estándar y la salida estándar de la JVM (System.err and System.out) van, por defecto, al dispositivo de salida regular, normalmente la ventana de terminal local. Se puede redireccionar la salida (ambas) a un fichero de log, de manera que el terminal no se llene de los datos de salida y además se podrá guardar para futuras referencias.

Uno de los defectos del modo manual es que no hay una monitorización de la JVM establecida. Si la JVM falla, hay que rearrancarla manualmente. Un paquete de monitorización externo, como mon http://www.kernel.org/software/mon/, es entonces una necesidad para cualquier site que use modo manual

Otro de los defectos del modo manual es que no se notifica a la JVM el rearranaque o parada del servidor web. Como regla, nunca se debería terminar un proceso Apache JServ usando el comano kill de Unix o el gestor de tareas de Windows NT. Cerrar una JVM de esta manera no permita una destrucción limpia de todos los servlets, para rearrancar o terminar limpiamente Apache JServ se debe usar la opción apropiada para Apache JServ, o sea:

-v    print server version
-V    print server version and details
-r    restart server
-s    stop server

Por ejempo, si el shell script de Unix anterior se grabara en un fichero llamado jserv, entonces se podría rearrancar el servidor usando el comando

jserv -r

 

Múltiples JVMs

Apache JServ permite tener cualquier número de JVMs. Esto puede usarse para dar soporte a seguridad mejorada, balance de carga, y tolerancia a los errores. La parte negativa es que cada JVM puede requerir recursos de memoria y procesdor significativos, lo que puede ser un factor a tener en cuenta a la hora de decidir cuantas JVMs permitir o qué hardware comprar.

El lado Java de Apache JServ escucha en un puerto específico las peticiones del servidor web. Si se ejecutan diversas copias (instancias) de Apache JServ en el mismo host virtual hay que asignar a cada instancia un número de puerto diferente. El puerto se especifica en el fichero de propiedades del motor, de manera que cada instancia requiere también un fichero de propiedades del motor separado. Estos ficheros pueden ser idénticos entre ellos, excepto en el número de puerto, o bien pueden ser completamente diferentes, ya que cada JVM es independiente de las otras.

Para ejecutar múltiples JVMs se neceista ejecutar Apache JServ en modo manual. La sección previa explica las diferencias entre el modo manual y el automático y muestra cómo lanzar una JVM en modo manual. La configuración de ejemplo siguiente muestra cómo configurar Apache JServ para usar diferentes JVMs para cada zona de servlets.

<IfModule mod_jserv.c>
ApJServManual on
ApJServMount /servlets1 ajpv11://localhost:9001/jvm1
ApJServMount /servlets2 ajpv11://localhost:9002/jvm2
ApJServLogFile /usr/local/apache/logs/mod_jserv.log
<Location /status/jserv/>
 SetHandler jserv-status
 order deny,allow
 deny from all
 allow from localhost
</Location>
</IfModule>

Las peticiones que empiecen por /servlets1 serán manejadas por la zona jvm1, que escucha en el puerto 9001, mientras que las que empiecen por /servlets2 serán manejadas por la zona jvm2, que escucha en el puerto 9002. Hay que arrancar las dos instancias de la JVM, la que escucha en el puerto 9001 y la que lo hace en el 9002, de esta manera (por ejemplo):

java org.apache.jserv.JServ 
/usr/local/apache/conf/jvm1.properties
java org.apache.jserv.JServ 
/usr/local/apache/conf/jvm2.properties 

También se puede derivar el trabajo de ejecutar la JVM hacia otros ordenadores. Además, como Java está disponible para diferentes plataformas, se puede usar el mismo código sin cambios en diferente hardware sin tener que recompilar, permitiendo utilizar cualquier hardware disponible. Se puede, por ejemplo, mezclar y coordinar servidores ejecutando Windows NT, Solaris, Linux, y HP/UX en diferentes plataformas.

Con modificaciones mínimas, la configuración precedente se puede usar para atender peticiones de dos máquinas diferentes (las porciones modificadas se muestran en negrita):

<IfModule mod_jserv.c>
ApJServManual on
ApJServLogFile /usr/local/apache/logs/mod_jserv.log
ApJServMount /servlets1 ajpv11://server1/zone1
ApJServMount /servlets2 ajpv11://server2/zone2
<Location /status/jserv/>
 SetHandler jserv-status
 order deny,allow
 deny from all
 allow from localhost
</Location>
</IfModule>

En este ejemplo, peticiones que empiecen con /servlets1 serán manejadas por la instancia de Apache JServ que se ejecuta en server1, mientras que las que empiezan por /servlets2 serán manejadas por la instancia de Apache JServ que se ejecuta en server2. Se necesitará, por supuesto, instalar el lado Java de Apache JServ en cada servidor, así como configurar apropiedamente los ficheros de propiedades del motor y de la zona para cada servidor. También podría necesitarse indicar la dirección IP del servidor web en la propiedad security.allowedAddresses en cada uno de los ficheros de propiedades del motor. Además, si se usa la directiva ApJServSecretKey, se deberá guardar el fichero de la clave secreta para cada servidor (copiando el fichero o bien mediante un sistema de ficheros compartido).

El balance de carga y la tolerancia a errores se añadió a Apache JServ en la versión 1.0b4. Un visión general con instrucciones están disponibles en How to: Scalability - Load-Blanacing - Fault tolerance por Bernard Bernstein y Jean-Luc Rochat. Esta funcionalidad es apropiada para sites con demandas altas (cargas elevadas) y/o que requieran fiabilidad incluso en el caso de la caída de una JVM.

Otro motivo para usar JVMs, separadas es proporiconar una mayor seguridad. Aunque el separar hosts virutales en zonas separadas es suficiente mientras se puede confiar en el personal que desarrolla los servlets, puede no ser apropiado si se quiere proporcionar un mayor nivel de seguridad. Por ejemplo, se puede querer asegurar que el código escrito para un host virtual no peda acceder a ficheros mantenidos en otro host virtual. Con la configuración de ejemplo dada en una sección previa, tanto vhost1 como vhost2 compartían una sola JVM que se ejecutaba con los mismos permisos (los de usuario del servidor Apache). Para completar el aislamiento de los dos hosts virtuales hay que usar el modo manual para lanzar dos JVMs separadas. La configuración de ejemplo de los host virtuales se reproduce debajo, con los cambios para el soporte de múltiples JVMs en negrita:

# directivas compartidas
LoadModule jserv_module libexec/mod_jserv.so
<IfModule mod_jserv.c>
ApJServManual on
ApJServLogFile /usr/local/apache/logs/mod_jserv_log
ApJServSecretKey DISABLED
<Location /status/jserv/>
 SetHandler jserv-status
 order deny,allow
 deny from all
 allow from localhost
</Location>
</IfModule>
NameVirtualHost 192.168.1.1

# directivas para vhost1
<VirtualHost 192.168.1.1>
ServerName vhost1.com
DocumentRoot /usr/local/hosts/vhost1/htdocs
<Directory /usr/local/hosts/vhost1/htdocs>
order allow,deny
allow from all
</Directory>
<IfModule mod_jserv.c>
ApJServDefaultHost vhost1.com
ApJServMount /servlets ajpv11://vhost1.com:9001/vhost1
</IfModule>
</VirtualHost>

# directivas para vhost2
<VirtualHost 192.168.1.1>
ServerName vhost2.com
DocumentRoot /usr/local/hosts/vhost2/htdocs
<Directory /usr/local/hosts/vhost2/htdocs>
order allow,deny
allow from all
</Directory>
<IfModule mod_jserv.c>
ApJServDefaultHost vhost2.com
ApJServMount /servlets ajpv11://vhost2.com:9002/vhost2
</IfModule>
</VirtualHost>

También se necesitará un fichero de propiedades del motor para cada maquina. Los ficheros pueden ser idénticos, excepto en el puerto, que debe ser el apropiado para cada JVM. Por ejemplo, un fichero de propiedades muy simple para vhost1.

security.allowedAddresses=192.168.1.1
security.authentication=false
port=9001
zones=vhost1
vhost1.properties=/usr/local/apache/conf/vhost1.zone.properties

El fichero de propiedades de vhost2 es casi idéntico:

security.allowedAddresses=192.168.1.1
security.authentication=false
port=9002
zones=vhost2
vhost2.properties=/usr/local/apache/conf/vhost2.zone.properties

Para completar el ejemplo, cada JVM debe ser lanzada como un usuario diferente. En Unix, se puede usar el comando su para lanzar la JVM con el usuario que se quiera. Por ejemplo:

% su - user1 -c \\
  "java -classpath 
	$CLASSPATH:/usr/local/jsdk/lib/jsdk.jar:/usr/local/jserv/lib \\
  ApacheJServ.jar org.apache.jserv.JServ \\
  /usr/local/apache/conf/vhost1.engine.properties"

% su - user1 -c \\
  "java -classpath 
	$CLASSPATH:/usr/local/jsdk/lib/jsdk.jar:/usr/local/jserv/lib \\
  ApacheJServ.jar org.apache.jserv.JServ \\
  /usr/local/apache/conf/vhost2.engine.properties"

También ser podría redireccionar la salida de cada instancia a un fichero de log, y/o usar las propiedades de log en cada fichero de propiedades del motor para dirigir los mensajes de log a los ficheros apropiados.

 

URL de estado

Apache JServ incluye un gestor especial y un servlet interno que se puede usar para monitorizar el servidor a través del navegador web. Si se usa la configuración de ejemplo proporcioanda con Apache JServ, entonces la URL para mostrar la página de estado es http://localhost/jserv/ (la barra final es necesaria). En el fichero de propiedades del motor también se puede habilitar la funcionalidad completa de estado añadiendo la siguiente propiedad:

security.selfservlet=true

que autoriza el acceso a la información sobre las zonas de servlets mapeadas.

La URL de estado da una página que lista los hosts configurados y los motores de servlet. Cada host configurado corresponde o bien al host por defecto del servidor web o bien a un host virtual. Cada motor de servlets mapeado corresponde aun motor de servlets distinto, tal como se haya especificado con la directiva ApJServMount directives en httpd.conf.

Haciendo click en uno de los hosts configurados se muestra información sobre ese host, incluyendo directivas de configuración, puntos de montaje y extensiones de fichero. Haciendo click en uno de los motores de servlets mapeados permite revisar la JVM, la ruta de clases (class path) y varios parámetros más, así como la configuración individual de cada zona.

En general, para habilitar el gestor de estado de Apache JServ hay que añadir una directiva Location en httpd.conf con una directiva SetHandler anidada, especificando le gestor jserv-status. Se puede mantener un estilo uniforme para todos los URL de estado (p. e., para Apache JServ, mod_perl, etc.) de manera que todos los URL de ese tipo empiecen con /status/; de esa manera se utilizaría una directiva Location como la siguiente:

<Location /status/jserv/>
SetHandler jserv-status
order deny,allow
deny from all
allow from localhost
</Location>

Se puede acceder a la URL de estado desde la máquina que aloja el servidor web usando una URL como http://localhost/status/jserv/. (la barra final es necesaria)

 

Solución de problemas

Apache JServ es una aplicación compleja. Una instalación y configuración exitosa requierent que tanto el servidor web Apache como el módulo JServ y una JVM estén correctamente instalados y configurados. Cada una de estas tareas implica varios subsistemas, incluyendo redes, permisos de fichero y de acceso, diferentes ficheros de configración y varias directivas de configración. Incluso usuarios experimentados se pueden confundir con tal cantidad de factores entrelazados.

El proyecto Java Apache incluye una comunidad de desarrolladores y usuarios experimentados. El web site del proyecto (http://java.apache.org) incluye, entre otras cosas, una cantidad significativa de información sobre Apache JServ. La página de FAQs on-line, mantenida por usuarios, y accesible desde la página inicial, es un recurso excelente. Hay temas de configuración y organización que yo no he tenido oportunidad de abordar, pero una revisión rápida de la constantemente creciente FAQ suele proporcionar una respuesta. La lista de correo es también un recurso excelente (para detalles ver el web site).

Ficheros de registro (log)

Las principales fuentes de información cuando se revisan los problemas de configuración son la URL de estado (descrita en otra sección) y los ficheros de registro del servidor (server log files). Antes de saber que ha pasado, habrá que habilitar el registro y examinar las entradas resultantes en los ficheros de registro. Entre Apache y Apache JServ hay unos cuantos ficheros de registro. Intentar hacer lo mejor que pueda para resumir qué contiene cada uno de ellos. Entre parentesis indico los nombres recomendados para cada fichero.

Registro de accesos (access.log)

Un registro de los URL pedidos desde el servidor.

Registro de errores (error.log)

Un registro de los errores encontrados por el servidor Apache. Incluye cosas como errores de 'file not found'.

Registro de mod_jerv (mod_jserv.log)

Un registro de los mensajes y errores encontrados por el lado C de Apache JServ (el módulo mod_jserv). Incluye mensajes relativos a comuniciones via AJP con el lado Java de Apache JServ y problemas de lanzamiento de la JVM en modo automático. Este registro puede deshabilitarse, en cuyo caso los mensajes se redirigen al registro de errores de Apache.

Registro de Apache JServ (jserv.log)

Un registro de los mensajes y errores encontrados por el lado Java de Apache JServ. Se puede configrar para incluir trazas de las excepciones de la pila, cabeceras de peticiones y respuestas, y información interna variada de debugging.

Podría ser necesario tener que mirar en todos los ficheros anteriores para encontrar la fuente de un problema.

Para habilitar registro en Apache se necesitan unas pocas directivas en httpd.conf (que vienen habilitades en la instalación por defecto), como por ejemplo:

LogLevel warn
LogFormat "%h %l %u %t \\"%r\\" %>s %b" common
CustomLog /usr/local/apache/logs/access.log common
ErrorLog /usr/local/apache/logs/error.log

Para habilitar el fichero de registro de mod_jserv se necesita tener la directiva ApJServLogFile en httpd.conf. Por ejemplo,

ApJServLogFile /usr/local/apache/logs/mod_jserv.log

Si se usa la marca DISABLED en vez de un nombre de fichero, entonces los mensajes se redirigirán al fichero de registro de errores (error log) de Apache, lo que puede facilitar un poco el seguimiento de errores, ya que habrá un fichero menos a monitorizar.

Para habilitar el fichero jserv.log hay que habilitar las directivas apropiadas en el fichero de propiedades del motor. Por ejemplo:

log=true
log.file=/usr/local/apache/logs/jserv.log
log.timestamp=true
log.dateFormat=yyyyMMdd.HHmmss.SSS: 
log.channel.init=true
log.channel.terminate=true
log.channel.serviceRequest=true
log.channel.authentication=true
log.channel.requestData=true
log.channel.responseHeaders=true
log.channel.signal=true
log.channel.exceptionTracing=true
log.channel.servletManager=true
log.channel.singleThreadModel=true

Un problema común son las restricciones en los permisos de acceso a los ficheros de registro, que no permiten al lado Java de Apache JServ escribir en su fichero de registro. El fichero jserv.log debe poder ser escrito por el usuario mediante el cual se identifica la JVM. En el modo automático esto significa que el fichero debe poder ser escrito por el usuario o grupo por el cual se identifica el servidor Apache, normalmente el usuario nobody. Si se ejecuta en Unix, las directivas de User y Group están puestas como usuario y grupo nobody, por lo que se puede necesitar hacer lo siguiente antes de generar el fichero jserv.log:

mkdir /usr/local/apache/logs
chgrp nobody /usr/local/apache/logs
chmod ug+rwx /usr/local/apache/logs
ls -ld /usr/local/apache/logs
drwxrwxr-x   2 root  nobody  1024 Jun 10 18:58 /usr/local/apache/logs/

Los ficheros de registro crecen bastante, y pueden contener mucha información que no es relevante para la tarea que se esté haciendo. Una manera de asegurarnos que sólo estamos viendo información esencial es limpiar los ficheros de registros y después hacer una prueba para regenerarlos sólo con la información relevante. Esto se puede hacer parando Apache, borrando los ficheros de registro viejos, y luego rearrancando apache. Hecho esto, se puede hacer una petición simple que genere un error. Por ejemplo, pongamos que el problema está en la URL http://localhost/servlets/HelloWorldServlet. Entramos esta URL en el navegador e intentamos acceder. En ese momento tenderemos ficheros de registro conteniendo sólo la información absolutamente relevante. Antes de hacer nada más, se pueden examinar y/o copiar los ficheros de registro.

Un método excelennte para analizar problemas es monitorizar continuamente los ficheros de registro. En Unix, se puede usar el comando tail -f para mostrar las entradas a medida que se escriben en los registros. Si además se está utilizando X Windows, entonces se pueden abrir múltiples ventanas de terminal, cada una de las cuales puede ser utilizada para monitorizar un fichero de registro diferente. A continuación hay un script de ejemplo que se puede utilitzar para monitorizar los ficheros de registro:

#!/usr/bin/perl
$loc=10;
$logdir="/usr/local/apache/logs";
$options="-bg black -fg green -font fixed -e tail -f";
foreach $file ("access.log", "error.log", "mod_jserv.log", "jserv.log")
{
	system "xterm -geometry \\"100x10+5+$loc\\" \\
			-T $logdir/$file $options $logdir/$file &";
	$loc += 180;
}

Se puede hacer más divertido combinando el comando tail con grep. Por ejemplo, se pueden examinar sólo comandos específicos (suponiendo, por ejemplo, que el programa registre el texto "SQLUpdate" junto a la información deseada):

tail -f /usr/local/apache/logs/error.log | grep SQLUpdate

Windows no tiene comandos como tail o grep. Lo mejor que he podido hacer bajo "vainilla Windows" ha sido cargar los ficheros de registro en el Bloc de Notas. Desgraciadamente, esto requiere recargar los ficheros cada vez que se quieran comprobar nuevos datos. Los puertos de Cygnus de varias utilidades GNU son mucho mejores, convenientemente envueltas en el paquete de utilidades Cygwin http://sourceware.cygnus.com/cygwin. Estas utilidades incluyen tail, grep y bash (un muy competente shell de Unix que sume el prompt de Windows en la más absoluta vergüenza).

Si no se sabe interpretar lo que pone en los ficheros de registro o cómo fijar las cosas, entonces se puede mirar en el código fuente de Apache JServ. Si se sabe leer código Java, entonces probablemente se puede uno imaginar lo que se espera que se ponga en los ficheros de configuración. También se puede mirar en el código fuente de mod_jserv, especialmente las fuentes de wrapper ((jserv_wrapper.c, jserv_wrapper_unix.c, and jserv_wrapper_win.c), que manejan el lanzamiento de la JVM en el modo automático

Problemas de arranque

Intenta ejecutar Apache Jserv en modo manual. La ejecución en modo manual permite el aislamiento del alcance de un problema. Si se puede arrancar la JVM en modo manual, entonces el problema estará en la configuración o en la organización de mod_jserv, esto es, el módulo mod_jserv no se carga o bien las indicaciones en httpd.conf no son correctas. Si no se puede ejecutar en modo manual, entonces el problema está en jserv.properties, en una de las zonas de propiedades o almacenes o en la configuración de Java en el ordenador.

Conflictos de puertos

Un problema común de arranque viene causado por un conflicto de puertos. Si se intenta arrancar Apache JServ mientras un proceso existente, típicamente otra instancia de Apache JServ, está ya ligado al mismo puerto, entonces se producirá el siguiente mensaje de error en el fichero de registro de mod_jserv (o en la salida del runtime de Java si se ejecuta en modo manual):

ApacheJServ/1.0b5: Exception creating the server socket: 
java.net.BindException: Address already in use

Para resolver este conflicto, se puede intentar ejecutar Apache JServ en un puerto diferente, cambiando la indicación de puerto en la directiva ApJServMount del fichero httpd.conf, y en la propiedad port en el fichero de propiedades del motor. También se debería comprobar la lista de procesos para ver si otra instancia de Apache JServ está ligada al mismo puerto.

Permisos de ficheros

Otra fuente común de problemas viene dada por los permisos de los ficheros, que no permiten acceso a los recursos que se piden. Se debería comprobar que el usuario como el que se ejecuta Apache JServ tiene acceso al fichero ApacheJserv.jar y a los ficheros de propiedades del motor y de la zona. Este usuario debería tener permiso de escritura en el fichero jserv.log. Si, por ejemplo, el usuario no tiene acceso al fichero ApacheJServ.jar entonces el fichero error.log tendría entradas como las siguientes:

/usr/local/jserv/lib/ApacheJServ.jar: Permission denied
Can't find class org.apache.jserv.JServ

Si el directiorio que contiene el fichero jserv.log file no puede ser escrito, entonces el fichero error.log puede contener entradas como:

ApacheJServ/1.0b5: Error opening log file: java.io.IOException:
Directory not writable: /usr/local/apache/logs

y al mismo tiempo, el fichero mod_jserv.log contendría entradas genéricas tales como:

[20/05/1999 13:04:00:044] (INFO) wrapper: Java VM restarting (PID=1690)
[20/05/1999 13:04:00:046] (INFO) wrapper: Java VM spawned (PID=1953,
 PPID=1690)
[20/05/1999 13:04:01:054] (INFO) wrapper: Java VM exited (PID=1690)

 

Desarrolladores múltiples

Los requerimientos para dar soporte a múltiples desarrolladores trabajando en un solo proyecto usando Apache Jserv son similares a los requerimientos necesarios para dar soporte a multiples clientes como ISP, excepto en que probablemente no habrá que estar excesivamente preocupado con la seguridad entre los desarrolladores.

Cada desarrollador debería tener su zona de servlets propia. Esto permite a cada uno instalar y probar cambios sin afectar a lo que haga el resto. En una instalación básica, se debería usar un sólo servidor web Apache, sin hosts virtuales y con Apache JServ ejecutándose en modo automático. Cada desarrollador tendría asignada su propia zona de servlets, nombrada de alguna manera lógica, como:

ApJServMount /alice/servlets /alice
ApJServMount /bob/servlets /bob

Otra manera de proporcionar esta funcionalidad es asignar a cada desarrollador un host virtual separado. Esto no ofrece ventajas específicas sobre el tener zonas separadas, pero puede proporcionar mayor flexibilidad a cada desarrollador para personalizar su entorno.

Otra configuración podría dar a cada desarrollador acceso a una instalación privada de Apache. Si los servidores están localizados y mantenidos en un solo servidor (por ejemplo para acceder a ficheros de datos o de configuración compartidos) entonces cada servidor deberá ser ejecutado con un número de puerto diferente (8080,8081, 8082, etc.). El desarrollador podrá entonces arrancar y parar el servidor Apache sin afectar a otros desarrrolladores y sin necesitar asistencia de un administrador del sistema. Alternativamente, los servidores pueden ser ejecutados en cada una de las máuinas locales de los desarrolladores, permitiendo asi al dessarrollador un control total sobre el servidor.

 

Seguridad

Las facilidades de seguridad proporcionadas por Apache y Apache JServ son accesibles a varios niveles. Estos se pueden dividir aproximadamente entre protecciones de comunicación y protecciones internas de Java.

En el nivel más externo se pueden filtrar los accesos a Apache y a Apache JServ usando un firewall o alguna otra herramienta externa. En el nivel siguiente, el servidor web Apache incluye características para limitar el acceso a URL específicas. Se puede usar la directiva Location y el control de acceso usando los ficheros htaccess para limitar el acceso a las URL que ejecutan los servlets. Por ejemplo, para proteger un conjunto de servlets para acceso sólo desde un dominio y usuario particular, se puede usar una directiva Location como la siguiente:

<Location /private-servlets>
order deny,allow
deny from all
allow from .domain.com
require user foo
 AuthType Basic
AuthName private
AuthUserFile /usr/local/apache/conf/users
</Location>

Este ejemplo restringe el acceso a las URL que empiecen con /private-servlets, lo que correspondería al punto de montaje para la zona de servlets a la que se le quiere restringir el acceso. Sólo el usuario foo accedientdo al site desde una máquina en el dominio .domain.com podrá acceder al sitio protegido. Para más información de la protección de URL, ver la documentación de Apache, para, por ejemplo, añadir usuarios o grupos adicionales o para usar un método de autenticación diferente.

Más allá del servidor web está el nivel de comunicación entre el servidor web y Apache JServ. Incluso si se protege completamente el acceso al servidor web aún se necesitará proteger el acceso al motor de servlets. Se puede limitar especificando las direcciones IP desde las que se podran aceptar conexiones usando un fichero de claves secreto, conocido sólo por el motor de servlets y por los clientes de confianza (trusted clients).

Para limitar las direcciones IP se usa la propiedad security.allowedAddresses en el fichero de propiedades del motor. Por ejemplo, para añadir la siguiente línea

security.allowedAddresses=192.168.1.2,196.168.1.3

daría acceso al motor de servlets sólo desde las direcciones IP indicadas.

Se puede añadir seguridad adicional usando un fichero de claves secretas y un string de cambios generado aleatoriamente. Ambas características estan activadas en el fichero de propiedades del motor:

security.authentication=true
security.challengeSize=5
security.secretKey=/usr/local/apache/conf/jserv.secret.key

El fichero de claves secretas debe ser conocido también por el cliente Apache Jserv (mod_jserv), así que hay que incluir la directiva ApJServSecretKey en el fichero httpd.conf:

ApJServSecretKey /usr/local/apache/conf/jserv.secret.key

El fichero de claves secretas debe contener datos aleatorios. Debería ser sólo legible por mod_jserv y el motor de servlets. Una limitación de esta aproximación es que cualquier código Java ejecutado por el motor de servlets puede leer el fichero de claves secretas, así que sólo a personal de confianza se le debería permitir instalar servlets.

En Apache JServ se puede gestionar la seguridad usando múltiples zonas de servlets para separar código y objetos. El código ejecutado dentro de una zona no tiene acceso al código ejecutado en cualquier otra zona, e inclose se pueden usar zonas de servlets para particionar rutas de clases (class path), ya que las clases incluides en el almacén de una zona no son accesibles por otra zona (a menos que las clases se añadan explícitamente a esa zona).

Cuando se usa una sola JVM, el código ejecutado en Apache JServ tiene acceso a recursos del sistema y de disco. Se puede dar más seguridad ejecutando múltiples copias de Apache JServ en JVMs completamente separadas. Cada JVM se ejecuta en su propio entorno de proceso y puede ser ejecutada con identificador de usuario único, lo que permite el uso de protecciones del sistema operativo a nivel de fichero y procesos

Java se diseño para ser un lenguaje seguro, e incluye métodos propios para limitar las operaciones que el código puede hacer. También incluye un sistema de tipos seguro y un verificador bytecode que permite que sólo se ejecute código valido. Es más dificil crear accidentalmente agujeros de seguridad en Java que en otros lenguajes populares (por ejemplo, a través de metaevaluaciones de entradas del usuario o por errores de sobrecarga del buffer). Por supuesto, aún es posible escribir software inseguro en Java, es sólo que el lenguaje en sí es menos propenso a ser la fuente del problema.

Java incluye métodos propios para prevenir operaciones no autorizadas. Las maquinas de los usuarios, donde se ejecutan los applets de Java, siempre han estado protegidas por estas características de segurirad. El servidor, donde se ejecutan los servlets, no ha tenido en cambio este nivel de protección, así que los servlets de Java y otro código Java ejecutado en el servidor no ha sido restringido por estrictas políticas de seguridad. Es posible, al menos teóricamente, añadir un gestor de seguridad (JDK 1.1) o bien personalizar una política de seguridad (JDK 1.2) para Apache JServ. En el JDK 1.2 es posible especificar una política de seguridad personalizada para cargarla en la JVM. Cualquiera puede desarrollar una política apropiada para su entorna, aunque la documentación de Sun no es tan fácil de seguir como uno esperaría. Hasta la fecha, no hay ningún gestor de seguridad o política de seguridad en Apache JServ, aunque hay planes para añadir esa funcionalidad en futuras versiones.

 

Depuración

Se pueden usar los metodos de registro en javax.servlet.ServletContext para registrar los mensajes en el fichero de registro de Apache JServ (p.e., jserv.log), o incluso escribir directament en System.err o System.out. Se puede hacer mucha depuracion con los comandos de log, aunque puede ser algo tedioso y puede ser mejor usar un depurador real.

El lado Java de Apache Jserv se ejecuta como un aplicaci´on Java con un metodo main estatico en la clase org.apache.jserv.JServ. Los servlets se ejecutan dentro de esta aplicacion, lo que significa que se puede usar cualquier depurador de Java para depurar Apache JServ y los servlets.

El JDK de Sun incluye el depurador jdb. Para usar jdb, se puede arrancar Apache JServ en modo manual (ver la seccion de ejecucion del modo manual para mas detalle). En resumen, para ejecutarlo en modo manual, hay que poner la propiedad ApJServManual en on en httpd.conf, y luego ejecutar manualmente Apache JServ desde la linea de comandos. Se puede adaptar el siguiente codigo de shell script de Unix para lanzar Apache JServ en modo manual usando jdb.

#!/bin/sh
properties=/usr/local/apache/conf/jserv.properties
log=/usr/local/apache/logs/jserv_manual.log
CLASSPATH=$CLASSPATH:/usr/local/jsdk/lib/jsdk.jar
CLASSPATH=$CLASSPATH:/usr/local/jserv/lib/ApacheJServ.jar
jdb org.apache.jserv.JServ $properties

 

Afinar el rendimiento

Las dos pérdidas principales de rendimiento de Apache JServ se deben al registro y a la rellamada automática de clases. Gran parte del retraso del registro (logging) se debe a los muchos objetos creados y gestionados para el registro. La rellamada automática de clases puede ser particularmente lenta si hay bastantes ficheros de clase separados. Para deshabilitar el registro en el lado Java, hay que establecer a false la propiedad log en el fichero de propiedades del motor. Para deshabilitar la rellamada autmática de clases, hay que poner a false las propiedades autoreload.classes y autoreload.file en el fichero de propiedades de la zona.

Otro sumidero de rendimiento es el pequeño tamaño máximo e inicial para los procesos que tienen por defecto algunas JVMs. Esto resulta en una recolección dememoria excesiva y/o en una cambio de tamaño del heap. En el modo automático se pueden usar las propiedades de wrapper.bin en el fichero de propiedades del motor para pasar valores para las opciones -ms y -mx al runtime de Java. Por ejemplo,

wrapper.bin.parameters=-ms32m
wrapper.bin.parameters=-mx128m

(para más opciones, consultar la documentación del propio runtime de Java.)

Se pueden deshabilitar algunas de las características de autenticación de seguridad en Apache JServ. Eliminando la propiedad security.secretKey y estableciendosecurity.authentication a false, se puede eliminar el tiempo gastado en conexiones de autenticación entre el cliente Apache JServ y el servidor. Sólo se debería eliminar esta autenticación, sin embargo, si se está seguro que se protege la instalación por otros métodos y/o si la ganancia en el rendimiento justifica la pérdida en seguridad.

También se puede ganar un rendimiento adicional optimizando el código Java propio. Dos herramientas útiles para perfilar son OptimizeIt! de Intuitive System yJInsight de IBM. OptimizeIt trabaja mejor con JDK1.2, dado que tiene una instrumentación más avanzada que JDK1.1.

Si afinando Apache JServ y optimizando el código propio no se han obtenido las ganancias de rendimiento buscadas, entonces se puede investigar el usar una JVM diferente. Cualquier JVM compatible con JDK 1.1 puede ser usada con Apache JServ. Sun, IBM y Microsoft hacen JVMs competitivas. Los vendedores están todos mejorando el rendimiento de las JVMs. Por ejemplo, Sun lanzó HotSpot en Abril de 1999, que ofrece mejoras de rendimiento sobre la JVM normal de Sun y se orienta principalmente a Java para servidores.

También se puede explorar la compilación a código nativo, que compila fuentes Java o bytecodes a código máquina nativo. EWl producto líder actualmente para compilación a código nativo es TowerJ http://www.towerj.com de Tower Technologies. La compilación a código nativo, sin embargo, puede dar mucho trabajo y sermenos flexible que los bytecodes portables de Java.

Con el balance de carga se puede dividir la carga entre múltiples servidores. Esta aproximación, sin embargo, comporta varios temas administrativos que no estan presentes con un solo servidor. Comprar hardware mejorado es probablemente una solución más simple que intentar mantener múltiples servidores, pero el balanceo de la carga puede ser, en cambio, el único método para conseguir el rendimiento que se necesita. Una visión general, con instrucciones de configuración, se encuentra en How to: Scalability - Load-Blanacing - Fault tolerance por Bernard Bernstein y Jean-Luc Rochat.

 

Funcionalidades añadidas

By installing Apache JServ on your server you have increased your options for server-side software. A growing number of Java servlets and generic Java libraries are being developed. You can write your own servlets from scratch, or you can integrate existing servlets into your environment.

Page Compilation Servlets

Una categoría muy util de servlets, conocidos como page compilation servlets, se pueden usar para añadir contenido dinámico a un site. Estos servlets analizan el fichero fuente, extraen e interpretan unos tags (marcas) especiales y generan una salida que es una combinación del fichero original y los tags interpretados.

Un servlet típico de compilación de páginas es Apache JSSI. Éste es un producto del proyecto Java apache que proporciona inclusiones de servidor para servlets de Java (Apache JSSI se puede bajar de http://java.apache.org.) Se puede añadir fácilmente contenido dinámico a un documento HTML ya creado añadiendo un tag 'servlet' especial. Apache JSSI ejecuta el servlet especificado por el tag y reemplaza el tag con la salida del servlet.

Por ejemplo, asumiendo que se ha instalado Apache JSSI y un serlvet llamado DateServlet que escribe la fecha actual, en el siguiente ejemplo se ve cómo incrustar la salida del servlet en un fichero HTML:

<html>
<head>
<title>Fecha</title>
</head>
<body>
<h1>Fecha</h1>
<servlet name="DateServlet">
</servlet>
</body>
</html>

La salida después de acceder la página anterior podría ser

<html>
<head>
<title>Fecha</title>
</head>
<body>
<h1>Fecha</h1>
11 de Abril de 2001
</body>
</html>

(el texto substituido se muestra en negrita)

Los servlets de compilación de páginas extraen la localización del fichero a analizar de la información de ruta extra que hay en la URL: cuando se hace una petición de un fichero que se ha de servir a través de un servlet de este tipo. la URL es algo así como esto:

http://dominio/zona/servlet/ruta

donde zona es el punto de montaje de la zona de servlets, servlet es el nombre del serlvlet de compilación de páginas, y ruta es la ruta relativa al fichero a compilar. Por ejemplo, usando Apache JSSI,

http://dominio/servlets/org.apache.servlet.ssi.SSI/products/file.html

Esta URL pasaría la ruta /products/file.html al servlet Apache JSSI, que entonces devolvería cualquier código HTML del fichero original así como el resultado de la ejecución de cualquier servlet incrustado (mediante el tag servlet)

Si se quiere que el servlet de compilación de páginas pueda manejar ficheros en cualquier localizacón arbitraria del servidor web, entonces hay que añadir un gestor de manera que Apache JServ pueda pasar cualquier fichero acabo en un sufijo particular al servlet de compilación de páginas. Para hacer esto, hay que añadir una directiva ApJServAction al fichero httpd.conf. Por ejemplo,

ApJServAction .jhtml /servlets/org.apache.servlet.ssi.SSI

Ahora cada vez que un documento acabado en .jhtml sea pedido, Apache JServ invoacara al servlet Apache JSSI.

Una vez se tienen documentos con un sufijo particular servidos a través del servlet de compilación de páginas, se podria añadir una entrada a la directiva DirectoryIndex en el fichero de configuración de Apache (httpd.conf), de manera que se pueda usar un fichero como ese como el fichero por defecto de un directorio. Por ejemplo,

DirectoryIndex index.html index.jhtml

En general, usar un sufijo especial es la manera preferida para invocar un servlet de compilación de paginas. Usar un sufijo es mejor que usar URLs que contengan una zona de servlets y el nombre del servlet porque esconde detalles internos del servidor a los usuarios. Si no se quiere usar un sufijo especial (por ejemplo si se está añadiendo contenido dinámico a un site existente) entonces se puede usar mod_rewrite para reescribir URLs que contienen el sufjio .html a URLs que invoquen el servlet en cuestión. Para ver un ejemplo de este tipo de aplicación, ver la sección de uso de mod_rewrite con Apache JServ).

JavaServer Pages

Con JavaServer Pages (JSP) se puede incrustar código Java directamente en un documento HTML. El código Java se compila automáticament cuando el fichero que lo contiene se modifica, los bytecodes compiladors se ejecutan entonces a través de la JVM y la salida es entregada por el servidor web junto con el código HTML que la rodeaba. JSP proporciona integración entre el código Java y HTML, la especificación y una referencia de implementación se pueden encontrar en el sitio web de Java de Sun, en http://java.sun.com/products/jsp.

Hay como mínmo dos implementacions libres y públicamente accesibels de programas que permiten incrustar código Java en documentos HTML: GNU Server Pages (GSP) y GNU JavaServer Pages (GNUJSP). Estos productos son esfuerzos de desarrollo independientes. Desde que la versión 1.0 de la especificación de Sun de las JSP salió recientemente, ninguno de los productos se adapta aún a ella, pero se pueden utilizar estos programas para desarrollar paginas web. Tanto GSP com GNUJSP estan escritos como servlets de Java normales, lo que significa que deberían trabajar con cualquier motor compatible de servlets en cualquier sistema operativo. Además de estos programas libres hay también implementaciones comerciales de JSP.

GSP

Esta sección muestra cómo se puede añadir GSP a una instalación de Apache JServ. El añadir GSP ilustra diversos puntos, incluyendo servlets de compilación de paginas, mapeo de sufijos de ficheros y uso de ficheros de propiedades y registro (log) para un servlet (por supuesto, se puede usar cualquier otro servlet de compilación de páginas con Apache JServ).

GSP se puede bajar del website de Bitmechanic http://www.bitmechanic.com. Las siguientes instrucciones ser refieren a la versión 0.86 de GSP, que es la versión corriente más accesible a la hora de escribir esto.

Configurar GSP consiste en:

  1. Crear un directorio en el que GSP pueda almacenar dinámicamente los ficheros de clase compilados.
  2. Añadir diferenes propiedades a fichero de propiedades de la zona de servlets.
  3. Crear un fichero de propiedades de GSP.
  4. Opcionalmente, añadir una directiva ApJServAction a httpd.conf.
  5. Probar la instalación.

Estos pasos se explican con más detalle debajo.

1. Crear el directorio de clases

GSP necesita un directorio en el que pueda escribir dinámicamente los ficheros de clase compilados, por ejemplo /usr/local/apache/gsp-classes, pero se puede poner este directorio donde se quiera. Por ejemplo, si se estan configurando múltiples hosts virtuales, se podría poner esto de manera que cada host virutal tuviera su propio directorio. Este directorio necesita poder ser escrito por el usuario como el qual se ejecuta Apache JServ (p.e. nodoby).

2. Añadir propiedades al fichero de propiedades de la zona

La necesaria configuración de los servlets puede ser hecha añadiendo las siguientes líneas al fichero de propiedades de la zona. Se necesitará, por supuesto, ajustar los paths para que se correspondan con las localizaciones de los ficheros de nuestro sistema.

repositories=/usr/local/java/gsp-0.86/gsp-0.86.jar
repositories=/usr/local/apache/gsp-classes
servlet.gsp.code=com.bitmechanic.gsp.GspServlet
servlet.gsp.initArgs=propfile=/usr/local/apache/conf/gsp.prop
erties

3. Crear el fichero de propiedades de GSP

GSP usa su propio fichero de propiedades. Las propiedades de ejemplo que vienen con GSP incluyen comentarios que explican las directivas. A continuación hay un fichero de ejemplo gsp.properties.

logger.filename=/usr/local/apache/logs/gsp.log
parser.classdir=/usr/local/apache/gsp-classes
parser.javac=/usr/local/java/jdk/bin/javac
parser.extraclasspath=/usr/local/java/gsp/gsp-
0.86.jar:/usr/local/apache/gsp-classes
parser.classreloader=com.bitmechanic.gsp.GspClassLoader

4. Añadir la directiva ApJServAction a httpd.conf

Para que cualquier documento acabado en .gsp sea procesador por GSP hay que añadir la siguiente directiva a httpd.conf:

ApJServAction .gsp /servlets/gsp

Para permitir también índexar el directorio usando .gsp hay que añadir una entrada para .jsp a la directiva DirectoryIndex en httpd.conf, por ejemplo:

DirectoryIndex index.html index.gsp

5. Prueba

Rearrabcar Apache, y probar entonces la instalación de GSP copiando los ficheros .gsp del directorio de pruebas de la distribución a nuestro directorio raíz de documentos y luego acceder a los documentos. Por ejemplo,


cp /usr/local/java/gsp/examples/date_test.gsp 
/usr/local/apache/htdocs
lynx http://localhost/date_test.gsp

Esto podría no ejecutarse correctamente la primera vez, y entontces se debería buscar errores en los ficheros de configuración (httpd.conf, propiedades del motor, propiedades de zona y propiedades de GSP). Cuando se buscan los errores, no hay que olvidar mirar en todos los ficheros de registro (.log), incluyendo el fichero de registro de GSP, especificado en la propiedad logger.filename en el fichero de propiedades de GSP.

 

Conclusión

Apache JServ todavía está en una versión beta mientras esto se escribe, aunque la versión final v1.0 está previsto que salga el 14 de Junio. La versión 1.0 sólo soporta JSDK2.0, ya que JSDK2.1 se lanzó mientras Apache JServ todavía estava en desarrollo (beta). Se planea un soporte completo para JSDK2.1 para la próxima release, y de hecho ya se está trabajando para tener una completa compatibilidad. También hay algunos esfuerzos en marcha para mejorar la funcionalidad y respuesta de Apache JServ.

Apache JServ es un motor de servlets flexible, de código abierto (open-source), disponible para muchos tipos de sitios. La gran base de usuarios del servidor web Apache y la creciente popularidad de Java prácticamente aseguran un interés continuado en Apache JServ. Como proyecto de código abierto, tienes acceso completo al código fuente y puedes corregir errores y enviar parches directamente al grupo, o, si demuestras interés y una habilidad razonable, directamente a los archivos de código fuente. El proyecto Java Apache ha evolucionado desde su meta inicial de crear el motor de servlets Apache JServ, y ahora actúa como un cobertor para diferentes proyectos de código abierto en Java. Un grupo entusiasta e informado de desarrolladores y usuarios mantiene los proyectos en permanente evolución y provee una valiosa asistencia.

 

Recursos

Proyecto Apache http://www.apache.org

Proyecto Java Apache http://java.apache.org

JSDK de Sun http://java.sun.com/products/servlet/index.html

JavaServer Pages de Sunhttp://java.sun.com/products/jsp

GNU Server Pages (GSP) http://www.bitmechanic.com

GNU JavaServer Pages (GNUJSP) http://www.klomp.org/gnujsp

Intuitive System's OptimizeIt! http://www.optimizeit.com

IBM's JInsight http://alphaworks.ibm.com/tech/jinsight

Service monitoring daemon http://www.kernel.org/software/mon

Utilidad Cygwin de Cygnushttp://sourceware.cygnus.com/cygwin

TowerJ http://www.towerj.com


Ari Halberstadt, 1999 (ari@shore.net)
La versión original de este artículo, " Configuring and using Apache JServ", se puede encontrar en la página personal de Ari Halberstadt ( http://www.magiccookie.com)
Traducido por Manel Guerra, 2001

cialis generique 20mgviagra a parislevitra cialispays viagra vente librecialis 20mg canadakamagra gel 100 mgbuy cialis onlinecanadian cialisviagra du peroucanadian viagracialis prescriptionviagra vente libre franceviagra i doserviagra par correspondancecialis professionalpharmacy viagracialis bas prixviagra au canadaacheter kamagra gelacheter viagra 50mgcialis prix 20mgviagra kaufenachat cialis en pharmacieprix du viagra 50 mgcheap viagraviagra africainlevitra originalacheter du cialis sans ordonnanceacheter du cialiscommander cialisposologie cialisacheter viagratadalafil moins chervente viagra marocviagra parapharmaciecialis 5 milligrams pilulesou se procurer du viagraacheter du cialis en pharmacieviagra maisonfaut il une ordonnance pour du cialisviagra sans ordonnances francecialis 20mg francetadalafil posologievente de cialis en francecommender du cialisprix levitra pharmacieacheter cialis canadacialis en ligne francemedicament cialis 20mgviagra au quebeccialis once a dayviagra genericviagra ukcomment commander du viagratarif du viagraou acheter viagra sans ordonnancecialis femmevardenafil generiquekamagra ukviagra vente libre espagnekamagra softprix du levitra 20mgviagra bleucialis en allemagnecialis generique tadalafilcommande cialiscialis for salegel kamagralevitra 5mg prixprix cialis en francesubstitut au viagraachat cialis en ligneacheter viagra par internetcommander kamagraachat de levitraprix du cialis en pharmacieviagra pharmacieviagra en belgiqueviagra espagneacheter kamagra en franceles generiques du viagraviagra super actifacheter du levitraachat kamagra gelcommander du cialislevitra generique 20mggenerique viagra francecialis ordonnanceorder cialisviagra naturel pour hommegenerique sildenafillevitra sur ordonnancetrouver viagraou acheter du kamagra a parishimalaya viagrapilules viagraviagra internetviagra generiqueviagra usacheter kamagra belgiqueprix du viagracialis tarifsildenafil oral jelly kamagraprix du viagra en pharmacieviagra en lignecialis au meilleur prixvente de viagra en lignecomment acheter du viagra en suisseacheter du viagraviagra meilleur prixvente cialis belgiquecialis prix officielprix cialis 5prix officiel viagrasildenafil citrate tabletsadolescent viagracomprar viagracialis medicamentcialis generique en lignecialis franceacheter generique cialisviagra gratuitviagra franceviagra algerielevitra cherviagra prix au marocviagra au luxembourgkamagra 100mg pas chervend viagragenerique sildenafil citratesildenafil pas cherprix cialis belgiqueviagra generique francecialis original 20mgle viagraduree efficacite levitraprix du cialis au marocou acheter cialis en lignecialis 2 5mgviagra shoplevitra achatviagra doseachat levitra en francetarif cialisprix du cialis 10viagra pas cher parisoral jelly kamagracialis pas cheracheter pilule viagraviagra naturelleviagra 50 prixviagra sur pariskamagra 100mg gelle viagra est il en vente libre en pharmacievente cialis generiqueviagra jeunevente en ligne cialiscialis prix en pharmacieviagra ou achetervente viagra generiqueviagra herbalachat cialis pas chermaroc viagraviagra soft tabs 100mgviagra pharmacie prixcout viagraviagra pour femme faireacheter viagra suisseacheter cialis en belgiqueacheter viagra en lignecialis generique prixprise viagracialis deutschlandviagra canadianmedicament cialis 20trouver du viagra en franceviagra promoprix viagra au marocachat du viagracialis prix 5mgviagra en thailandecialis 20mg tadalafilkamagra oral jelly achetercialis tadalafil prixcialis posologieacheter levitra sans ordonnancevente viagraviagra pour femme en franceacheter du viagra en franceviagra for menkamagra sildenafil citrateacheter kamagra oral jellypeut on acheter du viagra en pharmacie sans ordonnanceprix viagra 50medicament cialisviagra contre indicationscialis en pharmaciepilule bleue viagraviagra prix belgiqueprix cialis francelevitra achetercialis 20mg moins cherou trouver viagraprix cialis en belgiqueviagra chineachat viagracialis 20 mg tadalafilcialis pas cher en franceacheter en ligne viagraou acheter du levitraprix levitra 20mgprix viagra 100mgcialis generique 10cialis en vente libreviagra en vente libreequivalent viagra naturelviagra amsterdamprix boite viagrapharmacie buy cialisviagra linekamagra frle tadalafil cialisou se procurer viagracout du viagraachat kamagraprix levitraviagra effet sur femmeviagra 25 mg prixviagra professionalacheter viagra quebecgenerique cialis cialis 1x20mgle viagra sans ordonnancekamagra bruxellesviagra pour hommeou acheter du viagra en francele viagra pour les jeunesachat kamagra francegenerique viagracialis pharmacie moins chergenerique viagra en franceprix de viagra au marocachat viagra pariscialis 20mg prix pharmacieachat cialis 20mgou acheter du viagra sur internetcitrulline viagraacheter generique viagraviagra en francecommande levitravente de cialis sur internetlevitra quebecachat viagra pour femmecialis 20mg en francele viagra prixkamagra oral jelly uklevitra generique 10mgviagra 20mgprix du cialis 5mgviagra soft tabscialis prix discountviagra free onlineachat kamagra 100achat viagra sans ordonnancevente cialis en suissele viagra pour hommeconcurrent du viagraacheter cialis belgiquegenerique du levitraou commander cialisacheter du viagra en belgiqueviagra buyviagra professionnelviagra prix canadaviagra boiteprix du viagra en pharmacie quebecviagra commanderacheter levitra en ligneviagra generique achetercialis 5 mg comprimcommander cialis en ligneorder viagrasildenafil 100mgachat cialis 5mgcialis pharmacie en lignegenerique cialis 10mgprix en pharmacie du viagracialis vente libreacheter viagra sans ordonnancemedicaments cialisrecherche viagraviagra indienpharmacie cialiscommander tadalafilcialis dosesildenafil 50 mgcialis commandecialis 50mgcomparateur de prix viagracialis for womenviagra petit prixkamagra pas cherkamagra commandecialis suisseviagra prisesuper cialisachat viagra onlineautre que viagraacheter cialis en lignecomment acheter du viagra sans ordonnancevente de cialis sans ordonnancecialis discountou acheter du viagracialis pharmacieviagra de himalayaachat cialis prokamagra oral jelly viagra generiquesite fiable cialisviagra japonviagra en algerieviagra legalviagra pour femme prixviagra masculinou acheter du viagra sans ordonnanceacheter cialis au canadaachat viagra pas cherviagra pour femme au quebecgenerique du viagraprix en pharmacie du cialiscialis pour femmelevitra pharmacieviagra marocprix cialis generiqueacheter du cialis en lignecialis le moins cherkamagra piluleskamagra fastcomparatif prix viagracommander levitrakamagra indeacheter cialis 20tadalafil softcialis 2 mgpharmacie online cialisprix cialis 5mg en pharmaciekamagra oral jelly 10 sachetssildenafil tablets 100mgviagra pour la femmeviagra pharmaprixacheter viagra en espagnevends viagravente viagra parisviagra a montreallevitra prix marocfemme et viagragenerique viagra belgiqueviagra naturel maroccialis montrealprix viagraviagra conditionnementviagra herbepharmacie en ligne levitraacheter en ligne cialiscialis expressviagra en vente libre en franceacheter vardenafilviagra pour jeuneviagra avec ordonnancecialis prix suisseprix viagra en pharmaciecialis commanderou acheter du cialis sur internetcomparateur de prix cialisviagra andorrebuy viagra in canadaou acheter le viagraprix cialis viagratarif levitraviagra posologiecialis 100viagra 18 ansachat de viagra en suissetadalafil pas cheracheter cialis sans ordonnanceachat generique cialiskamagra livraison rapideprix du viagra en pharmacie en francecialis generic canadale cialisvente levitracialis 5mg prix en pharmaciequel est le prix du viagralevitra en pharmacieviagra venteprix cialis pharmacieboite de cialisviagra pour femmeviagra discountvente en ligne viagracialis acheterpromo cialiscialis one daygenerique levitraprix de levitraachat viagra naturelkamagra shople viagra est il en vente libreprix cialis pharmacie parisprix viagra francecomprimes cialisacheter sildenafil 100 milligramscialis moins cher parisachat levitra generiqueacheter viagra generiquetadalafil achatviagra canada onlineachat cialis franceprix cialis marocprix du levitra en baisseacheter viagra paristadalafil 10achat cialis en suissecialis en algerieachat cialis quebecprix cialis 10 mgcontre indication viagracialis prix maroclevitra 20mg generiqueviagra 100mgacheter viagra marocproduit similaire au viagravente viagra canadaacheter viagra canadawoman viagraachat viagra en suisseequivalent du cialiscommander du viagrakamagra moins cherle kamagraviagra himalayaviagra softeffet viagraviagra le moins cherviagra pour femme achata vendre viagrageneric viagra cialisviagra le prixgenerique tadalafilviagra 100vente tadalafilkamagra generiqueviagra 50 ou 100 mgviagra generic canadaachat viagra generiqueprix kamagra oral jellyacheter viagra en ligne en francevente cialis en belgiquecialis 20mg en pharmacieacheter viagra en pharmaciepilule viagracialis 10mg prixkamagra oralacheter kamagra oral jelly en francenatural viagraboite de viagraviagra libreviagra aux plantesmedicament levitraacheter cialis nettadalafil genericviagra 100 prixcialis meilleur prixou avoir du viagrageneric cialis tadalafilcialis fiableprix du cialis 5 mg en pharmaciecialis online canadaprix de cialiscialis 20mgviagra orderacheter viagra femininparapharmacie cialisacheter cialis 5mgbelgique viagrasubstitut viagracommander viagrasachet kamagralevitra baisse de prixsildenafil citrate tablets 100mgcialis naturelviagra canadaacheter du viagra a parisviagra pricecialis generique canadatadalafil 5mgcialis 5mg pas chercialis ukprix kamagraviagra achat en lignecanadian pharmacy cialisle viagra marocainmedicaments levitrakamagra plusviagra prix officielviagra en pharmacieviagra generique en lignele viagra des femmesdosage viagrakamagra pour femmeviagra a quel agele prix du viagra au marocviagra en vente libre en belgiquecialis generique 10mglevitra 5mgviagra au femininviagra thailandekamagra oral jelly belgiquecialis dose quotidienneacheter du tadalafilviagra generique en francecialis en pharmacie sans ordonnancecialis espagnebuy viagra ukacheter viagra en belgiqueviagra femininele viagra des merscomparer prix viagrafaut il une ordonnance pour du viagraacheter cialis pariscialis au marocprix cialis au marocviagra alternativele viagra en tunisiecialis comparatif prixcialis generique softtarif viagraviagra originalcialis dosagekamagra onlineviagra au maroccialis au canadala viagragenerique cialis en franceviagra pas cherviagra en ligne pas cheracheter cialis 10mgviagra pour femmse procurer du viagraacheter viagra au quebecprix viagra belgiquevente cialis en ligneviagra des incascialis traitementcialis internetle viagra naturelcheap generic viagra co ukachat cialis originalgeneric viagrakamagra achatsuper viagraviagra belgique prixviagra femmecialis 10mgviagra en tunisieprix du viagra en pharmacie en belgiquepeut on acheter du viagra sans ordonnanceviagra en parapharmacieviagra et femmedose kamagrasite kamagraprix cialisviagra vente libre belgiquecialis 10mg generiqueposologie du viagraacheter viagra veritabledose cialisou acheter viagraprix cialis 2 5mgacheter viagra montrealviagra tunisieviagra comparatifachat kamagra oral jellyposologie du cialisprescription du viagraachat cialis viagraviagra ordonnanceviagra sans ordonnancesautre que le viagravente de cialis en ligneproduit viagraprix du viagra en francegenerique viagra discountcialis prix de venteviagra efficaceviagra jellyviagra impuissanceviagra dopageacheter cialis ou viagratadalafil soft tablets 20mgachat en ligne cialiskamagra acheterfaut il une ordonnance pour le viagraprescription viagracialis generique 20cialis moins cheronline viagracialis marocviagra generique canadasoft cialislevitra en lignecialis tadalafilcialis en indeviagra online canadacialis 50dosage levitracialis en pharmacie avec ordonnancekamagra soft tabstadalafil generiqueacheter du kamagracheap generic viagrapilule cialiscialis dailyviagra commandeviagra france ordonnancetarifs cialiscialis en andorredu viagraviagra tarifdosage cialisgenerique cialisacheter viagra 50 milligramsviagra en ligne franceachat viagra franceprix viagra en francecialis 10medicament comme viagralevitra canadaviagra pour femme en pharmacieviagra non generiquegenerique cialis 20mgacheter cialis moins cheruk viagraachat cialis en franceviagra marocainacheter cialis au quebecacheter viagra en pharmacie sans ordonnanceviagra aux herbes hornprix levitra lyontarif du levitraarginine et cialisviagra sur le netcialis sur ordonnancegeneriques viagraviagra sous ordonnanceou acheter du cialissite cialispilule levitrakamagra canadaviagra prix en francecialis par internetviagra indiacialis activecialis luxembourgcialis le prixles effets du viagracialis prix canadaacheter tadalafil 20mgachat tadalafilviagra gelcialis authentiqueprix cialis en pharmacieou trouver du viagra sans ordonnancele viagra du tibetviagra 50mg prixprix du cialis en franceacheter du viagra en pharmacie sans ordonnanceachat de cialismedicament tadalafilviagra moins cherbuy kamagracialis 5 mg generiquecialis 20mg achatprix cialis pharmacie francecialis generique indevente de kamagrafille viagravardenafil prixviagra a vendreou acheter cialis generiquesildenafil posologiebaisse de prix levitracialis 20 mgpharmacie en ligne viagraviagra pharmacie belgiqueviagra indeandorre viagratadalafil tabletsacheter du viagra au canadaachat vrai viagraobtenir viagraviagra generique sildenafilviagra generique achatprix viagra 100copie viagraviagra chez les jeunescialis generique discountsur quel site acheter du viagracialis 20mg prix en pharmacieviagra en pharmacie prixacheter viagra internetviagra vente en pharmacieacheter 4 gratuit viagralevitra en suisseachat cialis canadaacheter cialis 5 milligramscomparer prix cialiscialis inefficacelevitra 20mgtadalafil 20mgviagra vertviagra generic onlinedosage du viagrabuy viagra onlinecialis au luxembourgcialis one a dayachat vardenafilacheter kamagra 100mgsildenafil citrate 100mglevitra sans ordonnancesuper kamagraacheter cialis pas cherprix cialis 5mgkamagra 100mgkamagra oral jelly 100mgviagra belgiquecialis livraison expresslevitra generiquekamagra 100mg oral jellylevitra tarifviagra vegaacheter viagra pas cherkamagra suissecialis livraison 24hlevitra 20 prixachat viagra montrealboite cialisviagra usalevitra ordonnancecanadian pharmacy viagraviagra himalayenou trouver du cialisprix levitra 20achat levitrageneric viagra onlinele prix de viagra au marockamagra jellyviagra achetercialis genericpilule bleu viagracialis softviagra generique marocou commander du viagrakamagra discountachat viagra suisseviagra professionelacheter cialis tadalafilviagra online canadian pharmacyacheter cialis en francegeneriques cialisvente de viagra en belgiqueonline viagra nowsildenafil 100autre medicament que le viagraachat de kamagracialis 10 prixcialis 20 prix en pharmaciecialis 40cialis belgiquelevitra commanderacheter viagra belgiqueposologie levitravente viagra sans ordonnanceviagra quebecviagra 50mgpharmacie en ligne cialisordonnance cialistadalafil cialisbuy cialis genericcommander cialis en belgiquele levitraacheter viagra pour femmeprix du cialis 10mgpeut on acheter du viagra sur internetherbal viagrageneric tadalafille tadalafilviagra en vente libre en pharmaciecialis une fois par jourbuy viagra canadaviagra canadian pharmacyafrican viagralevitra en vente libreviagra turcou acheter viagra generiqueprix du vardenafilviagra chez les femmesprix du cialisachat cialis belgiquecialis prix en belgiqueviagra online storepilules cialisbuy viagraacheter viagra en francelevitra maroccialis 5 mgvente libre viagrageneric viagra canadafemme viagramen health kamagratadalafil acheterlivraison rapide de viagracialis mgfaux cialisgeneric cialisvente libre viagra belgiquetadalafil e20levitra professionnelcialis pharmacie parisviagra femininviagra des femmesvardenafil 20alternative au cialiscommander du kamagraviagra naturel pour femmecomment acheter cialisvardenafil 20mgviagra rapideviagra ou autreviagra sans ordonnance belgiquelevitra 20levitra suissekamagra ventecomment acheter du viagra en franceviagra prescriptionviagra en vente libre en suisselevitra femmeprix du levitra en belgiquecialis originalcialis 20mg acheterviagra livraison 48htrouver kamagraacheter cialis en toute securiteviagra pharmacie parisachat cialis sur internetviagra du maroccialis prisekamagra thailandeacheter viagra moins cherou acheter du vrai viagraviagra fillecomment acheter du viagra en pharmacievente viagra belgiqueviagra medicamentcialis prix parislevitra 40 mgprix du cialis en suisseviagra pour femme canadacialis en venteprise du viagrakamagra francegenerique de viagrato buy cialisviagra pharmacie sans ordonnanceviagra generique belgiquejelly kamagraprendre cialisacheter tadalafilcialis gelou acheter le cialisviagra mgpharmacie viagraviagra en herbeachat de cialis sur internetviagra parisprix viagra marocgenuine viagravente kamagraou trouver du viagra a pariscialis sur internetachat cialiscommander cialis pas chercialis prix franceviagra equivalentle viagra peruvienpharmacy cialisviagra livraison discreteacheter viagra originalkamagra co ukachat levitra 20mgcialis prix belgiqueachat viagra en lignecialis generique pas cherprix du tadalafilprix du viagra au maroccialis indienbuy cialis online canadacialis pariscialis pas cher parisacheter du viagra en ligneviagra prix franceacheter viagra au canadaacheter vrai cialisgenerique cialis pas cheracheter du viagra pour femmefemale pink viagrale viagra pour les femmesrecherche cialisviagra achat franceviagra sur internetviagra sur ordonnanceviagra en pharmacitarif cialis 20viagra onlinevente viagra en tunisiekamagra posologiecialis journaliercommande viagracialis chez la femmecialis tunisieachat de viagra en francecommander kamagra oral jellylevitra 10viagra 150prix du cialis 10mg en pharmaciele prix de viagraviagra achat belgiqueachat en ligne viagracomment trouver du viagralevitra au marocachat cialis 20buy generic cialiscommande kamagralevitra posologiecommander cialis 20mgviagra naturel planteacheter cialis quebeccialis prixgeneric levitracialis 40 mgvente cialisposologie viagrabuying viagra onlineviagra 50cialis pas cher toulousevente libre de viagrakamagra 50cialis 20mg prixsildenafil citrateou acheter cialis en francecialis ordonnance ou pasbuy levitracialis prix pharmacievigorex sildenafilacheter du kamagra en francevente de viagrafaux viagraviagra for saleviagra a acheterle prix du levitraprix pharmacie cialisqui prescrit le viagraviagra belgique prescriptionacheter du cialis en belgiqueviagra et ordonnanceorigine viagraequivalent de viagracialis generique belgiqueacheter levitra en franceorder viagra onlinecialis super active 20mglevitra 40acheter cialis 10 milligramsacheter levitra 20mgcialis avec ordonnancecialis buyacheter viagra au marocpharmacy online cialiscialis generique fiablegel viagralevitra 20mg prixou acheter du viagra a parisviagra du tibetviagra ou generiquecialis achat francekamagra jelly 100mgsildenafil femmesildenafil jellyviagra en suissepink viagraacheter kamagracialis tadalafil 20mgou acheter levitrabuy viagra online canadase faire prescrire du viagraboite viagraviagra francaiskamagra sans ordonnanceprix cialis 20 mg comprimacheter du viagra sur internetsildenafil citrate gelviagra chez la femmelevitra dosagepharma cialislevitra medicamentandorre cialisgenerique levitra 10mgcialis 5kamagra oral jellysildenafil generiquecialis ou acheterviagra naturelviagra ou similaireviagra pour les femmesvente viagra francemeilleur prix cialistrouver viagra parisgenerique cialis softkamagra cheapvente viagra en lignecialis super actifcommander cialis canadaou commander viagraacheter cialis sur internetprix du cialis en espagneviagra du nepaleffet kamagra oral jellyviagra faut il une ordonnancesans ordonnance viagrameilleur prix viagracialis 5gviagra hong kongmeilleur site pour acheter cialisacheter levitrapharmacie en ligne kamagravente de levitraposologie tadalafilbuy cialis in canadaequivalent cialiscialis generiqueviagra en anglaisachats cialisprix du viagra 100mgcialis conditionnementlevitra moins chertadalafil prixprix du levitra en pharmacieviagra super activeviagra prix en pharmacieprix du viagra en belgiqueviagra en grande surfaceachat de cialis en lignecialis 20 mg comprimviagra for womencomparateur prix cialisje veux du viagramedicament viagrakamagra marseilleacheter cialis franceviagra pillscialis a vendretarifs viagrakamagra 100pays vente libre viagraviagra au herbebuy viagra online ukcommande de cialisviagra femalevardenafil 10mglivraison rapide cialisou trouver du cialis pas chercialis super activeprix du levitra 10mgbuy levitra discountprix cialis 20mgacheter viagra sur internetviagra pour les jeunescialis indiaviagra en allemagnecialis 20mg le prixacheter du viagra pas chernouveau cialisviagra 100mg prixcialis achatlevitra prix pharmacieprix du sildenafilcommande cialis generiquebaisse prix levitraachat viagra pharmacieviagra bruxellesviagra sur les femmescommander cialis genericpeut on se procurer du viagra sans ordonnancecialis commercialvente de cialisacheter du viagra generiqueprix du cialis 20prise de cialiscialis generique pharmacieachat de viagra en ligneviagra pharmacie ordonnanceou trouver du levitraachat cialis generiquesildenafil 100 pilulesviagra sildenafilachat viagra sur internetviagra womencialis en suisseviagra europeviagra 25mgcommande de viagradelivrance viagrafausse ordonnance viagracialis 20mg pas cherdosage sildenafilviagra en 24hacheter viagra pharmacieequivalent viagra pour femmeparapharmacie viagracheap cialiscialis orderviagra pour femmesmeilleur site viagraprix levitra en pharmaciequel viagra choisirvente cialis 20mgle prix de cialisachats viagracialis 5mgcialis 100mgcialis in franceou peut on se procurer du viagrakamagra belgiqueviagra prix suisseachat cialis en europeachat cialis internetacheter viagra onlineprix cialis 10mg en pharmacievente viagra quebeccomment acheter du cialismedecin viagranouveau viagragenerique du cialisachat cialis acheter cialiscialis generique en belgiquecialis indeacheter viagra franceviagra canada pharmacyviagra expresslevitra 10mgfemale viagradose viagraviagra cheapviagra livraison 24hviagra luxembourgcialis en ligne canadapris du viagratarif du cialiscialis comprimcomparatif prix cialiscialis en lignepeut on acheter viagra sans ordonnancele prix du viagracialis venteprix viagra pharmacieacheter levitra en suisse4 gratuit viagracialis lyonachat viagra en franceachat cialis 10mgacheter du cialis sur internetmedicament generique cialiscialis femininviagra vente libre en pharmacieordonnance pour cialisacheter kamagra franceachat cialis suisseachat viagra en ligne canadavente de viagra sans ordonnancelevitra en belgiqueacheter viagra generique en francecialis usacialis en franceequivalent du viagragenerique de cialistadalafil 20 milligrams 20cialis en belgiquecialis pas cher en pharmaciecialis 20mg andorrekamagra indiakamagra chewable tabletsite viagralevitra prix en baisseviagra naturalviagra gaykamagra 100 chewable tabletcialis jellyviagra en andorreprix medicament cialiscommander cialis en francelevitra 10mg prixcialis 200prix du cialis pharmacieacheter du viagra en pharmacieviagra mauritaniecialis onlinepilule de viagraachat de viagraachat cialis moins cherviagra en indecialis sans ordonnancevente viagra suisseviagra peruviencialis 5mg prix pharmacieprix levitra 10mgviagra authentiquelevitra vardenafildosage du cialislevitra francecialis generique franceprix du levitraacheter sildenafilcialis original livraison rapidekamagra oral jelly pas cherviagra senegalcialis livraison rapideprix du viagra en suisseprix du cialis en belgiqueprise de viagramedicament generique viagraacheter cialis 20mgcommander cialis generiquevente en ligne de cialisachat viagra en belgiquecialis 20mg generiquekamagra oral jelly prixviagra prescription mprix du medicament levitrakamagra sildenafilbuy cialis canadaremboursement viagraobtenir du viagrapilule viagra pour femmecialis 5 milligrams prixcialis 20mg conditionnementviagra pharmacie francecialis 20viagra en europewomen viagrabuy cialiscanada viagraviagra en ligne en francekamagra marocacheter viagra naturelvente viagra en francecialis generique en francegeneric cialis 20mgcommander viagra en ligneou commander kamagraachat viagra quebeccialis pour hommecialis francaissite fiable viagracialis europetadalafil canadacialis angleterrecialis en tunisieviagra livraison expresscialis side effectscanada cialisou acheter cialisviagra vente librelevitra prix en pharmacietadalafil 20achat viagra internetmeilleur site pour acheter du cialisacheter cialis originallevitra en francele prix du cialisgenerique levitra 20pharmacie paris viagrakamagra oral jelly franceprise cialissildenafil citrate 50mgviagra prixequivalent au viagraviagra du pauvretrouver du viagracialis 10mg prix en pharmacietadalafil 10mgcialis sans ordonnance belgiquecialis sans ordonnance en pharmaciecialis avec ou sans ordonnanceacheter levitra generiquelevitra pour femmeordonnance viagraviagra roseviagra en gelle medicament cialiskamagra prixcialis andorreviagra en espagneviagra achatposologie kamagracialis soft tabsviagra echantillon gratuitkamagra sachetgenerique du viagra en pharmacierecette viagracialis effetlevitra 10mg generiqueviagra a vendre montrealvente viagra tunisieprocurer viagracialis 20 generiquelevitra belgiquecialis prix en francecialis vente en francecialis 2 5viagra aux herbespharmacie canadienne cialiscialis achat internetvente en ligne de viagracialis 5mg prixcialis quebeccialis mensuelachat viagra andorreviagra dosageequivalent viagralevitra pas cherventes viagracialis contre indicationblue kamagraprix levitra belgiqueviagra jeune hommeordonnance pour viagraprix de viagralevitra prixle cialis est il en vente librevente libre cialisgeneric cialis 30acheter cialis generiqueprix du cialis 20 en pharmacieachat viagra belgiquevente du viagraviagra livraison rapidekamagra gelviagra suisseviagra pharmacyacheter viagra a montrealcialis 30 mgviagra envoi rapidecialis canadaprix du medicament cialiscomment se procurer du viagra sans ordonnancecialis sans prescriptionviagra moin cherebuy tadalafilacheter cialisviagra par internetlivraison rapide viagratadalafil naturelviagra generique pas cherviagra commercialkamagra pas chere