J2EE og distribuerte systemer Leksjon 7: Installasjon av applikasjonstjener og JNDI



Like dokumenter
J2EE. Katalogtjenester, JNDI og Enterprise Beans

Installasjonsveiledning

JSP - 2. Fra sist. Hvordan fungerer web? Tjenerside script HTML. Installasjon av Web-tjener Et enkelt JSP-script. Ønsker dynamiske nettsider:

J2EE. CMP Entity Beans, Transaksjoner, JSP

Løsningsskisse, eksamen J2EE og distribuerte systemer 19.mai 2004

Guide for tilkobling til HIKT s Citrix løsning

Del 1: Overgang fra gammel hjemmeside til ny hjemmeside

Installere JBuilder Foundation i Windows XP

Kap 3: Anvendelser av Internett

Bruk av NetBeans i JSP-delen av Web-applikasjoner med JSP og JSF

Installere JBuilder Foundation i Mandrake Linux 10.0

HØGSKOLEN I SØR-TRØNDELAG

Installasjonsveiledning. Mamut. Oppdatering til versjon 12.1

DIPS Communicator 6.x. Installasjonsveiledning

I denne oppgaven blir du introdusert for programmeringsspråket JavaScript. Du skal gjøre den klassiske oppgaven Hei verden, med en katt.

Installasjon enbruker

Intentor Helpdesk - Installasjon Step #3: Microsoft Reporting Services

Releaseskriv versjon Vedr. INSTALLASJONSPROSEDYRER. Versjon Pr. 30. MARS 2012 Copyright. Daldata Bergen AS

1. Installasjon av web-tjener og teori

VMware Horizon View Client. Brukerveiledning for nedlasting, installasjon og pålogging for fjerntilgang

Enbruker-installasjon

J2EE og distribuerte systemer Leksjon 9: Session Beans

Oppgradering av Handyman til siste tilgjengelige versjon

Shellscripting I. Innhold

TOD063 Datastrukturer og algoritmer

6105 Windows Server og datanett

Velkommen som ny bruker av Uni Økonomi!

Kjernejournal. Pilotering - Javafri oppkobling

Teori om sikkerhetsteknologier

RUTEPLANLEGGINGSSYSTEM BRUKERVEILEDNING

Installasjonsveiledning for Ordnett Pluss

DDS-CAD 7 INSTALLASJON AV NETTVERKSLÅS. DATA DESIGN SYSTEM ASA Øksnevad Næringspark, 4353 Klepp st., fax , tel.: , e-post: dds@dds.

Java fra Eclipse til Evalanche

Hvordan laste ned og installere Java på Windowsplattformen

En liten oppskrift på hvordan jeg installert og fikk Xastir til å virke sånn at jeg ble synlig i APRS verden.

Kursdokumentasjon for Dreamweaver

Eksport og innsending

Installasjonsveiledning Visma Avendo Lønn, versjon 7.60 Oktober 2011

INF1000 Metoder. Marit Nybakken 16. februar 2004

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

Konfigurasjon av nettverksløsning for Eldata 8.0 basert på PostgreSQL databasesystem.

infotorg Enkel brukermanual

Kanter, kanter, mange mangekanter

Velkommen til Pressis.

Løse reelle problemer

som blanker skjermen (clear screen). Du får en oversikt over alle kommandoene ved å skrive,

1. NetBeans IDE: Lage en enkel mobilapplikasjon

Lotus Traveler - Manual for installasjon

Forord. Brukerveiledning

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

6105 Windows Server og datanett

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

HØGSKOLEN I SØR-TRØNDELAG

Installasjonsveiledning Visma Avendo, versjon 5.2

JOBOFFICE POCKETLINK FOR ANDROID Installasjons- og klargjøringsprosedyre, del 1

Publisering av statiske og dynamiske websider til klasserom.net fra Dreamweaver og MySQL

Klask-en-Muldvarp. Steg 1: Gjøre klart spillbrettet. Sjekkliste. Introduksjon

Brukermanual for Quizbuilder

6105 Windows Server og datanett

Øving 0 - Xcode TDT4102

Bruk av oppgaver og grupper i

Komme i gang med Skoleportalen

6105 Windows Server og datanett

CORBA Component Model (CCM)

Installasjon av Windows 7 og Office 2016

1. Introduksjon til J2ME

PowerOffice Server Service

Installere programvare gjennom Datapennalet - Tilbud

UI-View Installasjon og konfigurasjon for IGate + RX<->TX av meldinger og ingen ting annet!

Soloball. Steg 1: En roterende katt. Sjekkliste. Test prosjektet. Introduksjon. Vi begynner med å se på hvordan vi kan få kattefiguren til å rotere.

Introduksjon til. For studenter ved NTNU

J2EE og distribuerte systemer Leksjon 11: Entity Beans (CMP)

Vårt nettsted En håndbok for lokale nettredaktører i fylkes- og lokallag

Den er nettbasert, og man trenger derfor ikke installere et eget program for å bruke den.

Fra datax til Visma eaccounting

Innhold. Epostprogrammer og webmail.

Mamut. Installasjonsveiledning. Oppdatering til versjon Detaljert steg-for-steg veiledning i hvordan oppdatere ditt datax-program fra Mamut

Installasjonsveiledning

Huldt & Lillevik Ansattportal. - en tilleggsmodul til Huldt & Lillevik Lønn. Teknisk beskrivelse

Introduksjon til dataanlegget ved Institutt for informatikk. Marc Bezem Institutt for informatikk Universitetet i Bergen

Viktig informasjon til nye brukere av Mac-klient fra UiB

Lærebok. Opplæring i CuraGuard. CuraGuard Opplæringsbok, - utviklet av SeniorSaken -

Brukerveiledning digital eksamen i FLOWlock

FRC-Feeder-E. Et sikkert og raskt verktøy for overføring av data til File Record Converter Versjon 1.9

For mer informasjon om SQL Server 2014 Express, se Microsoft sine nettsider:

FTP Info til brukerne

Socket og ServerSocket

Uansett hvilken håndbok du benytter vil fremgangsmåten være den samme. I denne veiledningen benytter vi personalhåndboken som eksempel.

Husk at du skal ha to vinduer åpne. Det ene er 'Python Shell' og det andre er for å skrive kode i.

2 Grafisk grensesnitt 1

1 INNLEDNING Om Altinn Skjemaer som støttes INSTALLASJON OG OPPSTART Nedlasting Registrering...

Enkel veiledning for: GSM key3+

HØGSKOLEN I SØR-TRØNDELAG

Labquality/NKK ELEKTRONISK RESULTATSKJEMA VIA INTERNET. Åpning av skjemaet. Logg inn på Participant services. Velg resultatskjemaet

J2EE og distribuerte systemer Leksjon 10: Entity Beans (BMP)

81,9(56,7(7(7,26/2 'HWPDWHPDWLVNQDWXUYLWHQVNDSHOLJHIDNXOWHW

Kjenn din PC (Windows Vista)

Dennis Myhre Oblig 4 Wordpress Dokumentering og Eksamensoppgaver

Eksamen i Internetteknologi Fagkode: ITE1526

Brukerveiledning. Searchdaimon AS phone: Østensjøveien 34 fax:

Transkript:

J2EE og distribuerte systemer Leksjon 7: Installasjon av applikasjonstjener og JNDI Leksjonen er forfatters eiendom. Som kursdeltaker kan du fritt bruke leksjonen til eget personlige bruk. Kursdeltakere som ønsker å bruke leksjonene f.eks. til undervisning eller kursformål må ta direkte kontakt med forfatter for nærmere avtale. Copyright: Tomas Holt/TISIP Publisert 14.10.03. Frist innlevering av øvingsoppgaver 24.10.03 INNHOLD 1 KOMMENTAR TIL LEKSJONEN... 1 2 MOTIVASJON FOR J2EE... 1 2.1 GJENBRUK AV KODE OG KOMPONENTBASERT UTVIKLING... 1 2.2 J2EE OG ENTERPRISE BEANS... 2 2.3 APPLIKASJONSTJENER OG CONTAINER... 2 2.4.NET... 3 2.5 J2EE ER MER ENN EJB... 3 3 INSTALLASJON AV J2EE... 4 3.1 PLATTFORM FOR APPLIKASJONSTJENEREN... 4 3.2 MILJØVARIABLER... 4 3.3 START APPLIKASJONSTJENEREN... 4 3.4 NOE GIKK GALT VED OPPSTART AV APPLIKASJONSTJENEREN... 5 3.5 OK, TJENEREN KJØRER. HVA SÅ?... 5 3.6 APPLICATION DEPLOYMENT TOOL... 6 3.7 JNDI OG KLIENTPROGRAMMER... 9 3.8 TEST AV APPLIKASJONEN MED RUNCLIENT...12 3.9 PROBLEMER MED INSTALLASJON ELLER TEST AV APPLIKASJONEN?...12 3.10 KJØR KLIENTEN FRA EN ANNEN MASKIN...13 3.11 HVORDAN KJØRE HELLOWORLD UTEN RUNCLIENT?...13 4 JNDI OG KATALOGTJENESTER...13 4.1 SPI (SERVICE PROVIDER INTERFACE) OG DRIVERE TIL KATALOGTJENSTEN...14 4.2 HVORDAN ANGI HVILKEN DRIVER ELLER NAVNE-/KATALOGTJENESTE SOM SKAL BRUKES?...15 4.2.1 I klientprogrammet... 16 4.2.2 På kommandolinjen ved oppstart av programmet... 16 4.2.3 I en konfigurasjonsfil... 16 4.3 DISTRIBUERTE NAVNE-/KATALOGTJENSTER...17 4.4 INNLEVERINGSOPPGAVE...19 5 LENKER BRUKT I LEKSJONEN...21 6 OPPGAVER...21

1 Kommentar til leksjonen Les først igjennom denne leksjonen. I tillegg så skal du lese kapittel 1 i boka. Dette beskriver hvorfor bruke J2EE og Enterprise Beans. Les også kapittel 7 i boka med unntak av kapittel 7.5-7.7 2 Motivasjon for J2EE J2EE (Java 2 Enterprise Edition) er et rammeverk som er kommet for å hjelpe utviklere i utviklingen av store og krevende applikasjoner. Som leser av denne leksjonen er du (forhåpentligvis) i stand til å lage distribuerte systemer, enten vha. Java sockets eller Java RMI. Det er imidlertid en del begrensninger med disse teknologiene som blir klart i det øyeblikket du skal lage større og forretningskritiske applikasjoner. 2.1 Gjenbruk av kode og komponentbasert utvikling Utviklere prøver hele tiden å lage koden sin slik at den kan gjenbrukes ved senere anledninger. Dette er ikke en enkel oppgave av flere grunner: 1. Det er ofte vanskelig og tidkrevende å lage kode som kan brukes i andre sammenhenger (som man ikke har oversikt over når man lager koden). 2. Uerfarne utviklere blander kode med presentasjon. Dette gjør det vanskelig å gjenbruke deler av koden i andre sammenhenger der man vil ha en annen presentasjonsform. 3. Man vil gjenbruke allerede laget kode, men i andre miljøer. Et eksempel her kan være at man vil bruke allerede laget kode, men man vil bruke en annen database enn koden ble laget for i utgangspunktet. Dette kan kanskje høres ut som en grei skuring, men det er ikke nødvendigvis tilfelle. Kanskje har du brukt SQL-kode som kun er gyldig for akkurat det databasesystemet du har valgt å bruke. Denne koden må da endres hvis du velger et nytt databasesystem. 4. Reglene for deler av systemet endrer seg. Tenk f.eks. at det er laget et system med visse sikkerhetsregler. Administrator kan utføre bestemte oppgaver og vanlige brukere kan utføre andre oppgaver. Man ønsker å bruke dette systemet i en annen sammenheng, men i dette tilfellet vil man at brukerne skal kunne utføre noen av oppgavene som bare administrator er satt opp til å gjøre. Hvordan løse dette problemet? Det kommer selvsagt an på hvordan koden ble laget i utgangspunktet. I verste fall må man faktisk gå inn i koden og forandre den med rekompilering osv. Andre muligheter er selvsagt her også mulig, men det beskriver problematikken. 5. Systemet ble laget for maks 100 brukere, men nå har det blitt 200 brukere og systemet har store problemer med å takle så mange brukere. Det har blitt tregt og ustabilt på grunn av den store belastningen. Man har oppgradert tjenermaskinen med den aller beste maskinvaren tilgjengelig (ser bort fra supermaskiner da dette er altfor dyrt). Man står i en situasjon der man ønsker å spre systemet på flere tjenermaskiner. Komponentbasert utikling er en måte å utvikle deler av systemer på. Poenget er å lage komponenter som løser et begrenset problem. Hvis man i andre sammenhenger trenger å løse det samme problemet, skal komponenten kunne smettes inn i et annet systemet for å løse det samme problemet. Systemene vil dermed etter hvert kunne bygges ved å sette sammen komponenter. Man tenker seg at det vil bli marked for slike komponenter, slik at ved behov så 1

kjøper man ferdiglagde og ikke minst ferdigtestede komponenter. Dette høres kanskje litt for fantastisk ut? Det vi trenger er et rammeverk for å gjøre dette mulig. 2.2 J2EE og Enterprise Beans I J2EE har man laget et rammeverk for komponentbasert utvikling. I J2EE blir disse komponentene kalt Enterprise Beans, heretter kalt EJB. Dette må ikke forveksles med JavaBeans som er et rammeverk for å lage komponenter i J2SE. EJB er komponenter som kjører på tjenersiden i et system. Disse komponentene trenger en container som komponenten kjører i. Denne containeren tilbyr visse tjenester til komponenten. Hva slags tjenester trenger så en slik komponent? Disse tjenestene kan være av ulike slag. 2.3 Applikasjonstjener og container Containeren som vi snakker om ligger i en applikasjonstjener (en applikasjonstjener er en tjener som tilbyr applikasjoner). Det er altså denne tjeneren som tilbyr tjenester til de ulike komponentene i en applikasjon. En skisse over dette kan være slik: Applikasjonstjener Container Klient EJB EJB Database Sirklene her beskriver tjenester som applikasjonstjener/container tilbyr EJB ene. For eksempel kan du se at EJB en ved databasekontakt går via en tjeneste i containeren. Du kan også se at klienten må gå via containeren for å få kontakt med en EJB. Dette gjør at containeren kan autentisere brukeren før han får bruke EJB en. Figur 1: Oversiktsfigur Se på punkt 3, 4 og 5 i kapittel 2.1. Disse problemene kan faktisk løses ved at containeren tar seg av disse oppgavene. Punkt 3 beskriver problemer ved bruk av databaser. Hva hvis containeren sørger for kommunikasjon mot databasen? Dvs. at vi ikke skriver noe kode for kommunikasjon mot databasen i vår kode. Du tenker kanskje at dette kan ikke være mulig? Det er det faktisk, og vi skal gjøre dette i en senere leksjon. Det man gjør i dette tilfellet er at man lager en EJB, dvs. en Java-klasse som er laget etter visse retningslinjer, der det overhode ikke befinner seg kode for kommunikasjon mot databasen. Deler av databasekommunikasjonen vil faktisk containeren kunne skjønne selv, ut fra måten du har 2

laget EJB en på. Nå er selvsagt ikke containeren så lur at den uansett skjønner hvilke spørringer du vil ha utført mot databasen, dette løses med å legge disse spørringene i en egen fil. Dette er en XML-fil (altså en tekstfil) og kan f.eks. inneholde en beskrivelse som sier: Når metode A blir kalt opp så utfør spørringen select * from studenter og returner alle studentene. Hvis vi nå skulle ha behov for å endre spørringen, gjøres dette i XML-filen uten at vi må gå inn i selve Java-koden og forandre på denne. Punkt 4 beskriver problemer hvis man skulle finne på å endre på rettighetene i systemet. Dette problemet kan også løses vha. containeren. I alle tilfeller der vi vil ha begrenset tilgang til deler av systemet så spesifiserer vi også dette i en XML-fil. I denne filen kan vi f.eks. si at administrator har tilgang til å kalle opp metode A, mens vanlige brukere kan kalle metode B osv. Hvis dette skulle forandre seg så går vi ganske enkelt inn i denne filen og endrer på rettighetene. Det vil nå hele tiden være containeren sin oppgave å sjekke at brukeren har rettigheter til å kalle metodene han prøver på. Punkt 5 kan løses enkelt ved at man starter en applikasjonstjener på hver tjenermaskin, og at disse applikasjonstjenerne på en eller annen måte samarbeider om å betjene klientene. F.eks. kan de dele forespørslene likt seg i mellom. Akkurat hvordan dette gjøres vil være forskjellig fra applikasjonstjener til applikasjonstjener, men poenget er at det er mulig. Hver applikasjonstjener vil da inneholde EJB er som utfører forespørslene fra klientene. Du skjønner kanskje nå at poenget med J2EE-rammeverket er å flytte en del av ansvaret i systemet bort fra programmereren og over til applikasjonstjeneren/containeren og systemansvarlig. Vi har allerede sett at systemansvarlig kan forandre hvilke metoder brukerne kan kalle i systemet, uten at programmereren kommer inn i bildet i det hele tatt. (Dette er viktig fordi programmereren ikke nødvendigvis har forutsetninger for å bestemme hvem som skal ha tilgang til hvilke deler av komponenten som utvikles. Husk at poenget med å utvikle komponenter er at de skal kunne brukes i ulike sammenhenger). Det blir containeren sin oppgave å sjekke at brukeren har riktig rettighet. Programmereren slipper altså å skrive kode for å identifisere brukeren og å sjekke hvilke rettigheter han har, noe som sparer tid og også faren for feil (vi håper at de som har laget containeren har gjort en god jobb :-) 2.4.Net Det finnes også andre rammeverk enn J2EE for å lage komponenter der rammeverket tilbyr tjenester til komponentene. Microsoft har sitt rammeverk som heter.net. Det er forskjeller og likheter mellom disse rammeverkene. Vi skal imidlertid kun konsentrere oss om J2EE og begir oss ikke inn på noen diskusjon på forskjeller og likheter. 2.5 J2EE er mer enn EJB J2EE er et tillegg til J2SE og kan ikke brukes alene. Det er i sistenevnte API at vi finner alle de grunnleggende klassene som du fram til nå har brukt. Disse vil du selvsagt fortsatt bruke. J2EE inneholder klasser som generelt er kjekke i tjenerapplikasjoner. Java Mail API en er et eksempel her. J2EE er også som tidligere forklart et rammeverk for å lage komponenter (EJB er). Dette rammeverket er altså et sett med regler for hvordan slike komponenter skal lages, og ikke minst hvordan applikasjonstjeneren må oppføre seg, hvilke tjenester som må tilbys osv. 3

3 Installasjon av J2EE Du har allerede lastet ned J2EE SDK. Denne inneholder mer enn bare API en. Blant annet er det med en applikasjonstjener. Vi skal i dette kurset bruke denne som tjener til de EJB ene vi lager. Det første vi bør gjøre er derfor å sette opp miljøet slik at vi får startet denne tjeneren. 3.1 Plattform for applikasjonstjeneren Tjeneren som er med i J2EE-SDK 1.3.1 er beregnet på Linux, Windows NT og Windows 2000. Selv bruker jeg tjeneren på Windows XP (+ Linux) og det fungerer greit. Hvorvidt dette fungerer på Windows9x har jeg ikke erfaringer med. En ting som er sikkert er at dette ikke er en stødig plattform og av den grunn ikke bør brukes. Til testformål er det vel likevel mulig å bruke også disse plattformene. 3.2 Miljøvariabler Når du skal bruke J2EE så trenger du å sette noen miljøvariabler. Dette har du gjort i tidligere leksjoner (4 og 5), men under kommer en oppsummering på hva som må gjøres. For å bruke J2EE API en og medfølgende verktøy (f.eks. applikasjonstjeneren) må vi sette noen miljøvariabler. Hvis du ikke vet hvordan dette gjøres, se eget skriv om miljøvariabler (på web-siden til faget). JAVA_HOME Du må ha en miljøvariabel som heter JAVA_HOME og denne må peke på katalogen du har installert J2SE (altså din vanlige Java-installasjon). Dette bør være minst versjon 1.3. J2EE_HOME Du må ha en miljøvariabel som heter J2EE_HOME og denne må være satt til å peke på katalogen der du har installert J2EE. PATH PATH variabelen må inneholde katalogene <java-home>/bin og <j2ee-home>/bin. <javahome> og <j2ee-home> referer her til katalogene hvor J2SE og J2EE er installert. CLASSPATH CLASSPATH må inneholde <j2ee-home>/lib/j2ee.jar. Her refererer <j2ee-home> til installasjonskatalogen for J2EE. Dette må til for å kunne kompilerer Java-klasser som bruker J2EE API en. 3.3 Start applikasjonstjeneren Du bør nå kunne starte applikasjonstjeneren med å skrive følgende på kommandolinjen (- verbose gir ekstra informasjon): j2ee verbose Du bør da se noe slikt: J:\>j2ee -verbose J2EE server listen port: 1050 Naming service started:1050 4

Binding DataSource, name = jdbc/cloudscape, url = jdbc:cloudscape:rmi:cloudscape DB;create=true Binding DataSource, name = jdbc/db2, url = jdbc:cloudscape:rmi:cloudscapedb;crea te=true Binding DataSource, name = jdbc/minoppkobling, url = jdbc:cloudscape:rmi:cloudsc apedb;create=true Binding DataSource, name = jdbc/inventorydb, url = jdbc:cloudscape:rmi:cloudscap edb;create=true Binding DataSource, name = jdbc/estoredb, url = jdbc:cloudscape:rmi:cloudscapedb ;create=true Binding DataSource, name = jdbc/oracle, url = jdbc:oracle:thin:@baron.stud.idb.h ist.no:1521:orcl Binding DataSource, name = jdbc/db1, url = jdbc:cloudscape:rmi:cloudscapedb;crea te=true Binding DataSource, name = jdbc/xacloudscape, url = jdbc/xacloudscape xa Binding DataSource, name = jdbc/xacloudscape xa, datasource = COM.cloudscape.co re.remotexadatasource@383118 Starting JMS service... Initialization complete - waiting for client requests Binding: < JMS Destination : jms/topic, javax.jms.topic > Binding: < JMS Destination : jms/queue, javax.jms.queue > Binding: < JMS Cnx Factory : jms/queueconnectionfactory, Queue, No properties > Binding: < JMS Cnx Factory : jms/topicconnectionfactory, Topic, No properties > Binding: < JMS Cnx Factory : QueueConnectionFactory, Queue, No properties > Binding: < JMS Cnx Factory : TopicConnectionFactory, Topic, No properties > Starting web service at port: 8000 Starting secure web service at port: 7000 J2EE SDK/1.3.1 Starting web service at port: 9191 J2EE SDK/1.3.1 J2EE server startup complete. Som vi ser så er J2EE-tjeneren oppe og kjører. Hvis vi ser helt på toppen så kan vi også se hvilken port tjeneren lytter til. 3.4 Noe gikk galt ved oppstart av applikasjonstjeneren Fikk du følgende feil ved oppstart av applikasjonstjeneren? J:\>j2ee -verbose j2ee gjenkjennes ikke som en intern eller ekstern kommando, kjørbart program eller satsvis fil. Problemet er nok at du ikke har satt miljøvariabelen PATH riktig. Gå tilbake og sjekk dette. Hvis du fikk andre feil enn den vist over er nok sannsynligheten også stor for at du har satt en av miljøvariablene feil. Husk at det ikke må være mellomrom når du setter en miljøvariabel. Gå tilbake og rett opp dette. 3.5 Ok, tjeneren kjører. Hva så? Nå sitter du der med en aldeles utmerket fungerende applikasjonstjener, hva gjør du så? Poenget er vel å bruke den til noe fornuftig? Hvordan får vi dette til, vi har jo ikke lært å lage J2EE applikasjoner/komponenter? Det vi trenger er en allerede fungerende applikasjon som vi kan teste. 5

Last ned HelloWorld.ear fra Web-siden hvor du lastet ned denne leksjonen. 3.6 Application Deployment Tool HelloWorld.ear inneholder en J2EE applikasjon. Ear-filer brukes for å pakke hele J2EEapplikasjoner, og er en arkivfil som inneholder de nødvendige delene til en slik applikasjon. For å kunne bruke denne må den legges ut på applikasjonstjeneren du har kjørende. Hvordan dette gjøres vil avhenge av hvilken applikasjonstjener man bruker, men i vårt tilfelle skal vi bruke et verktøy som er med i J2EE SDK. Verktøyet heter deploytool og er et eget verktøy for akkurat vår applikasjonstjener. Sørg for at applikasjonstjeneren er startet og skriv på kommandolinjen deploytool. Du skal da få opp et grafisk brukergrensesnitt som ser noenlunde slik ut: Figur 2: deploytool Deploytool viser nå en oversikt over J2EE-applikasjoner på tjeneren din. Tjeneren er i dette tilfellet applikasjonstjeneren som kjører på localhost (denne finnes som default). Foreløpig har du ikke lagt ut noen applikasjoner på tjeneren så la oss gjøre dette. 6

Velg File>Open. Du får da opp en dialogboks. Let opp HelloWorld.ear (du husker vel hvor du lagret filen?). Velg denne filen og trykk Ok. Figur 3: HelloWorld Du bør nå ha et skjermbilde som er noenlunde likt det over (du må trykke på skillearket JNDI Names). Her ser vi at J2EE-applikasjonen HelloWorld består av to deler. HelloWorldJAR er en Enterprise Bean. I tillegg så består applikasjonen av en klient som heter HelloWorldClient og en klient som heter HelloWorldClientIndirectLookup (hvorfor vi har to klienter skal vi komme tilbake til neste leksjon). Det vi nå trenger å gjøre er å legge ut applikasjonen på tjeneren vår. Merk av applikasjonen HelloWorld (som vist i figuren) med musa. Velg så Tools > Deploy. Du får da opp et nytt vindu. 7

Figur 4: Legge ut applikasjon Sørg for å merke av for Return Client Jar. Du må også velge hva filen skal hete og hvor den skal lagres. Gi filen navnet HelloWorldClient.jar og lagre filen på samme katalog som du har lagret HelloWorld.ear. (Av figuren kan du se at jeg har lagrer min fil som HelloWorldClient.jar i katalogen d:\4\).trykk Finish. Applikasjonen vil da legges ut på tjeneren. Dette vises ved at HelloWorld dukker opp under Servers/localhost, se figuren under. 8

1 Ta opp vinduet applikasjonstjeneren kjører i. Du kan da se noe sånt som Application HelloWorld Deployed. Ok alt vel så langt. Nå har vi lagt ut applikasjonen vår på applikasjonstjeneren og vi har også en klient som kan brukes mot applikasjonen vår. Vi bør nå være i stand til å teste applikasjonen vår. Før vi gjør dette skal vi imidlertid se litt på hvordan klienten tar kontakt med en EJB. 3.7 JNDI og klientprogrammer Når vi skal koble oss opp mot en EJB i applikasjonstjeneren gjøres dette på en måte som er veldig lik den som brukes i Java RMI. I RMI så brukte klienten rmiregistret for å finne et fjernobjekt. Koden var noe slikt: MittFjernObject obj = (MittFjernObjekt)Naming.lookup( rmi://entjener.com/navnpåfjernobjektet ); Det som skjer da er at det sendes en forespørsel til rmiregistret på entjener.com der det spørres etter et objekt som heter NavnPåFjernObjektet. Rmiregistret vil da returnere et stub-objekt (stedfortreder-objekt) til klienten, som denne bruker for å kalle fjernobjektet som ligger på tjeneren. I J2EE har man valgt å ikke bruke RMI-protokollen for å finne tak i fjernobjekter. Vi bruker i stedet JNDI (Java Naming and Directory Interface). Grunnen er at dette er en mye mer fleksibel løsning enn å bruke rmiregistret. JNDI kan faktisk brukes mot rmiregistret, men også 9

mot andre navnetjenester/katalogtjenester (for dypere forklaring se kapittel 4). JNDI er altså et standardisert grensesnitt som kan brukes mot ulike typer navne/katalogtjenester (på samme måte som JDBC kan brukes mot ulike databaser). Applikasjonstjeneren (j2ee) bruker CORBA sin navnetjeneste i stedet for rmiregistret. Det første en klient må vite når den skal koble seg opp (lookup) mot et fjernobjekt (her EJB) er hvilket navn objektet er registrert ved. Da du la ut HelloWorld-applikasjonen ble det også opprettet et JNDI-navn for EJB en. Ved å bruke deploytool (se figuren under) kan du se at dette navnet er Hello. Jeg bestemte dette navnet når jeg lagde applikasjonen. I det du la ut applikasjonen ble dette navnet bundet i navnetjenesten (det er deploytool som sørger for dette) og klienter er nå i stand til å ta kontakt med EJB en. Figur 5: JNDI-navn på EJB La oss se på hvordan koden blir når vi lager en klient som bruker JNDI for å koble seg opp mot en EJB. Under vises klienten HelloWorldClient. Om du ikke skjønner alt i koden så ikke heng deg opp i dette. Du vil blant annet se at det brukes to klasser HelloWorldHome og HelloWorld noe som kan virke litt merkelig. La oss foreløpig si at dette er EJB en (dog dette er en sannhet med modifikasjoner). Vi skal i neste leksjon se nærmere på hvorfor koden blir slik. import javax.ejb.*; import javax.naming.*; public class HelloWorldClient{ public static void main(string args[]){ try{ System.out.println("starter"); Context context = new InitialContext(); System.out.println("etter context"); Object objref = context.lookup("hello"); System.out.println("ferdig med lookup "); 10

} } HelloWorldHome home = (HelloWorldHome) javax.rmi.portableremoteobject.narrow(objref, HelloWorldHome.class); System.out.println("ferdig med casting"); HelloWorld hello = home.create(); System.out.println("ferdig med create()"); System.out.println(hello.getHelloWorldString()); }catch(exception e){ System.out.println(e); } Det som er viktig for vår diskusjon her er uthevet med fet skrift i koden. Som du ser er det mange utskriftssetninger i denne koden. Dette er gjort for å gjøre det enkelt å finne ut hvor det skulle oppstå feil. Linjen Context context = new InitialContext(); henter en kontekst. En kontekst er her et sett med assosiasjoner mellom navn og objekter. Dette er altså analogt med det man finner i rmiregistret (hvert objekt er tilknyttet et navn som vi bruker når vi vil finne objektet). Når vi bruker JNDI kan imidlertid denne context en finnes gjennom rmiregistret eller en annen katalogtjeneste. Vi spesifiserer i vårt tilfelle ikke hvilken type context vi er ute etter, noe som gjør at CORBA sin navnetjeneste automatisk blir brukt. Det er denne som er vanlig i forbindelse med J2EE-applikasjonstjenere (mer om andre alternativer kommer senere). Når vi nå har fått tak i denne konteksten kan vi gjøre en lookup og finne det objektet vi er ute etter. Når det er snakk om EJB er vil vi normalt ikke gjøre lookup helt som vist under, men vi kommer tilbake til dette i neste leksjon. Object objref = context.lookup("hello"); I konteksten her er det altså bundet et objekt til navnet Hello. Som vi ser av koden over bruker vi metoden lookup() og denne returnerer en referanse til et fjernobjekt. Nå gjenstår det å sørge for å få castet denne referansen til riktig type. Dette gjøres slik: HelloWorldHome home = (HelloWorldHome)javax.rmi.PortableRemoteObject.narrow( objref, HelloWorldHome.class); Vi bruker altså PortableRemoteObject.narrow() for dette (i stedet for å caste direkte). Argumentene til metoden er referansen vi vil ha castet (objref) og hvilken klasse det er snakk om (HelloWorldHome). Fremgangsmåten her er definitivt litt mer tungvidt enn i RMI. Grunnen til at det må gjøres slik er at vi bruker RMI IIOP og ikke RMI som kommunikasjonsprotokoll. Dette innebærer blant annet at koden vil være kompatibel med CORBA-standarden som gir mulighet for å bruke andre programmeringsspråk enn Java (CORBA kan sammenliknes med RMI, men det er ikke knyttet mot Java, slik at andre programmeringsspråk også kan benyttes). Ok, da er det på tide å teste om applikasjonen vår fungerer. 11

3.8 Test av applikasjonen med runclient La oss nå prøve klienten i HelloWorld-applikasjonen og se hva som skjer. Klienten ligger pakket inne i filen HelloWorldClient.jar som du lagde med deploytool (du kan selv bruke f.eks. WinZip eller skrive jar xvf filenavn.jar på kommandolinjen for å se hva som er inne i en slik jar-fil). Denne Jar-filen inneholder nå alle filene som klienten trenger. Merk at dette er mer enn bare HelloWorldClient.class filen (blant annet så trengs interfacene til EJB en m.m.). Det er derfor lurt å bruke deploytool til å lage klienten. Når vi kjører slike J2EE-klienter er det ikke vanlig å gjøre dette direkte med java NavnPåKlasse. Vi vil i stedet bruke en batch-fil (dette er en fil som utfører flere kommandoer på en gang) som heter runclient.bat for Windows og runclient.sh for Linux. Denne batch-filen løser en del oppgaver for oss (for nærmere beskrivelse se kapittel 3.11). Før vi kan bruke runclient må vi sørge for å sette en miljøvariabel. Denne skal hete APPCPATH og skal peke på HelloWorldClient.jar. Det kan f.eks. løses slik (<sti> må skiftes ut stien hvor HelloWorldClient.jar ligger lagret). set APPCPATH=<sti>\HelloWorldClient.jar Bruk kommandolinjen og sørg for å stå på katalogen hvor HelloWorld.ear ligger lagret. Skriv deretter: runclient client HelloWorld.ear name HelloWorldClient textauth Merk at HelloWorldClient er navnet på klassen klienten ligger i (ikke navnet på Jar-filen). Du vil bruke samme framgangmåte for å kjøre andre klienter. Du vil da skifte ut HelloWorld.ear med aktuell Ear-fil og skifte ut navnet på klienten (APPCPATH må også endres). Du vil nå få beskjed om å taste inn brukernavn og passord. Dette er hhv. guest og guest123 (du kan også trykke enter to ganger). Du skal da få et følgende output: starter etter context ferdig med lookup ferdig med casting ferdig med create() HelloWorldBean says hello (Du kan oppleve at du får ClassCastException i siste linje, men la dette ligge. Vi skal i neste leksjon sørge for at dette problemet forsvinner). 3.9 Problemer med installasjon eller test av applikasjonen? Hvis du støter på problemer med installasjon eller test av applikasjonen, sørg først for å dobbelsjekke at du har gjort alt riktig. Hvis du fortsatt har problemer anbefaler jeg at du legger inn et innlegg på diskusjonsgruppa til faget (se fagets hjemmeside). Det er nok ikke utenkelig at andre har hatt samme problem, og kan fortelle deg hva som skal til for å løse problemet. 12

3.10 Kjør klienten fra en annen maskin Du har nå sett hvordan du kan lage en klient til en EJB og hvordan denne kan kjøres. Det er også selvsagt mulig å kjøre klienten fra en annen maskin enn den maskinen som applikasjonstjeneren kjører på. Den enkleste må ten å gjøre dette på er rett og slett å installere J2EE-SDK også på klientmaskinen og bruke runclient.bat. Du må da sørge for at både earfilen og klientens jar-fil ligger på klientmaskinen. For å få dette til å fungere trenger du i tillegg å gi beskjed om hvilken maskin JNDIcontext en skal hentes fra. I vårt tilfelle ligger navnetjenesten på samme maskin som applikasjonstjeneren (vi starter begge deler med å skrive j2ee verbose). Vi angir hvilken maskin navnetjenesten kjører på ved å sette (eller utvide) miljøvariabelen VMARGS til Dorg.omg.CORBA.ORBInitialHost=<maskinnavn>. <maskinnavn> må skiftes ut med navnet på maskinen applikasjonstjeneren kjører på (f.eks. enserver.com). 3.11 Hvordan kjøre HelloWorld uten runclient? Det er mulig å lage en frittstående klient som kjøres uten runclient.bat. (runclient.sh), men visse ting må man være klar over. Den innebygde sikkerhetsmekanismen i applikasjonstjeneren vil nå være satt ut av spill. Dvs. at du må selv sjekke om brukeren er den han utgir seg for... For å kjøre en J2EE-klient må filen j2ee.jar ligge i classpath. Interfacene som brukes av klienten må være tilgjengelig. Hvis du bruker deploytool vil disse ligge inne i jar-filen som blir laget for klienten ved bruk av deploytool. Ved å pakke opp denne jar-filen finner du en fil som heter ejb-jar-ic.jar. Inne i denne filen finnes alle nødvendige klasser og interface. Denne filen må derfor også ligge i classpath. 4 JNDI og katalogtjenester JNDI (Java Naming and Directory Interface) er som navnet sier et grensesnitt mot navne- /katalogtjenester. Forskjellen mellom en navnetjeneste og katalogtjeneste er at en navnetjeneste kun inneholder en mapping mellom et navn og et objekt. Rmiregistret som brukes i forbindelse med Java RMI er altså en navnetjeneste. Her bruker vi et navn til å finne fram til et objekt. Katalogtjenester tilbyr mer enn bare en mapping mellom navn og objekter. En katalogtjeneste kan ha flere opplysninger om objektet. Et eksempel kan være en katalogtjeneste som inneholder ansatte i en bedrift. Til hver ansatt (objektet) har man flere opplysninger. Det kan være ting som hvilket kontor personen har, hvilken e-post adresse osv. Slike tjenester vil ofte bruke en database. Det finnes mange ulike katalogsystemer.vi kan f.eks. se på en LDAPtjener (hva det innebærer å være en LDAP-tjener er ikke viktig her). La oss si at vi har lagret ansatte i en bedrift i en katalogtjeneste som støtter LDAP-protokollen (dette er protokollen som klienten vil bruke for å kommunisere med katalogtjenesten). Vi ønsker å finne ansatte ved AITEL som sitter i 3.etg. Syntaksen for dette vil da være noe slikt: ldap://aitel.hist.no/enhet=aitel, etg=3? 13

Poenget med å bruke en katalogtjeneste er at opplysningene ligger lagret en plass. I eksemplet over vil det være enkelt å finne opplysninger om ansatte fordi de nødvendige opplysningene ligger lagret en plass (vi kunne selvsagt ha benyttet et vanlig databasesystem i stedet). Har en ansatt sluttet vil det være enkelt å slette ham fra systemet da opplysningene (forhåpentligvis) ligger lagret en plass. Katalogtjenesten kan inneholde opplysninger om hvilke rettigheter brukeren har i systemet. Det vil da være enkelt for programmer å hente disse rettighetene og det vil være enkelt for en administrator i systemet å endre rettighetene. JNDI er som tidligere nevnt et grensesnitt mot navne-/katalogtjenester. Fordelen med en slik løsning er at vi bruker det samme grensesnittet uansett hvilken navne-/katalogtjeneste vi bruker. Denne løsningen er veldig lik den løsningen vi finner i JDBC (Java Database Connectivity). Her bruker vi ett Java-bibliotek uansett hvilken databasesystem vi bruker. Dette gjør at det er mye enklere å skifte mellom ulike databasersystemer uten å endre koden (vi endrer bare driveren). Skulle du imidlertid finne på å bruke SQL-setninger som kun fungerer på MySQL-databaser, må du også endre SQL-koden hvis du endrer databasesystemet til ORACLE. Det samme gjelder for JNDI, men her er det mye lettere å komme opp i slike problemer da syntaksen og mulighetene i ulike navne-/katalogtjenester kan variere mye. Bruker du JNDI er du ofte avhengig av å kunne noe mer om den underliggende katalogtjenesten. 4.1 SPI (Service Provider Interface) og drivere til katalogtjensten Figuren under viser en figur hentet fra http://java.sun.com. Den viser hvordan JNDI fungerer. Det nest nederste laget i figuren er JNDI SPI (service provider interface). I dette laget plugges drivere (også kalt service provider) for de ulike katalogtjenestene inn. Dette er som du ser helt analogt med det som skjer i JDBC. Når du skal bruke JNDI er du derfor avhengig av å ha driveren for riktig navne- /katalogtjeneste tilgjengelig. Denne kan enten skaffes via http://java.sun.com/products/jndi/serviceproviders.html eller direkte fra tilbyderen av navne- /katalogtjenesten. Noen drivere er med i SDK 1.4 (og 1.3). Dette er: com.sun.jndi.ldap.ldapctxfactory for LDAP versjon 3 com.sun.jndi.rmi.registry.registrycontextfactory for bruk mot RMI registret. 14

com.sun.jndi.cosnaming.cnctxfactory for CORBA sin navnetjeneste. Sistnevnte er den varianten vi vil bruke for at klienter skal finne EJB er i applikasjonstjeneren. Andre drivere som kan være aktuelle er: com.sun.jndi.dns.dnscontextfactory som brukes for å kommunisere med DNS. com.sun.jndi.fscontextfscontextfactory for bruk mot filsystemet com.novell.naming.service.nds.ndsinitialcontextfactory for bruk mot NDS. com.sun.jndi.nis.nisctxfactory for bruk mot NIS. Det er flere måter å angi hvilken driver vi vil bruke. Les kapittel 7.8 og 7.9 i boka for forklaring på de ulike måtene å løse dette på. Les også resten av kapittel 7 med unntak av 7.5 og 7.6. 4.2 Hvordan angi hvilken driver eller navne-/katalogtjeneste som skal brukes? I kapittel 3.7 ble det vist hvordan en klient kan bruke JNDI til å finne fjernobjekter. Der oppga vi ikke hvilken driver eller navne-/katalogtjeneste vi ville bruke. Resultatet var at det ble brukt standard driver og navne-/katalogtjeneste. Standard driver vil si driveren for CORBA sin navnetjeneste (com.sun.jndi.cosnaming.cnctxfactory). Med standard navne-/katalogtjeneste så brukes navntjenesten som ligger på nåværende maskin (localhost). Med andre ord koblet vi oss opp mot CORBA sin navnetjeneste på samme maskin som klienten kjørte på. Ofte vil det være slik at klienten kjører på en annen maskin enn maskinen der navne- /katalogtjenesten kjører. I kapittel 3.10 ble det vist hvordan vi kunne løse dette problemet. Denne løsningen gjelder imidlertid kun når det er snakk om å bruke CORBA sin navnetjeneste. I forbindelse med dette kurset vil denne metoden alltid føre fram, da det er denne navnetjeneren som brukes i forbindelse med applikasjonstjeneren j2ee. Det kan imidlertid være lurt å vite hva man skal gjøre hvis JNDI skal brukes mot andre navne- /katalogtjenester. Det er flere mulige framgangsmåter for å spesifisere hvilken driver man vil bruke og på hvilken maskin ønsket navne-/katalogtjeneste befinner seg. Jeg skal ikke gå dypt i detaljer på hvilke muligheter som finnes, bare ta de mest vanlige valg. For å angi hvilken driver som skal brukes setter vi en miljøegenskap (system property) slik: java.naming.factory.initial=com.sun.jndi.cosnaming.cnctxfactory For å angi hvilken tjener navnetjenesten befinner seg på kan vi gjøre følgende: java.naming.provider.url=iiop://th.idb.hist.no:1050 Her beskriver vi at provider.url=iiop://th.idb.hist.no:1050. Dvs. at vi bruker protokollen iiop (brukes mot CORBA sin navnetjenste), at maskinen heter th.idb.hist.no og at navnetjenesten befinner seg på port 1050. Akkurat hvordan miljøegenskapene settes kan variere. Det kan gjøres på 3 ulike måter 1. direkte i klientprogrammet 2. på kommandolinjen ved oppstart av programmet, 15

3. i en konfigurasjonsfil (Properties-fil). Disse mulighetene beskrives i de neste underkapitlene. 4.2.1 I klientprogrammet Hvis vi skal sette miljøegenskapene i klientprogrammet gjøres det slik: public static void main(string args[]){... Properties env = new Properties(); //vi bestemmer nå hvilken driver (service provider) som skal brukes //her bruker vi driveren for CORBA navnetjeneste env.setproperty("java.naming.factory.initial", "com.sun.jndi.cosnaming.cnctxfactory"); //vi bestemmer oppstartspunktet for oppslag i katalogtjenesten //her blir det file:/ da det er filsystemet vi skal bruke. env.setproperty( java.naming.provider.url, iiop://th.idb.hist.no:1050 ); Context context = new InitialContext(env);... } Det man gjør i dette tilfellet er å lage et Properties-objekt. Dette vil inneholde de miljøegenskapene man vil sette i forbindelse med JNDI. I objektet putter vi så miljøvariablene og tilhørende verdi (med metoden setproperty()). Tilslutt så oppretter vi JNDI konteksten vi skal bruke. Merk at vi her bruker env som argument på siste linje. Dette gjør at konteksten blir opprettet med de spesifikasjonene vi har gitt. 4.2.2 På kommandolinjen ved oppstart av programmet Denne måten å gjøre det på er det allerede vist et eksempel på. Se kapittel 3.10. 4.2.3 I en konfigurasjonsfil Vi lager først en konfigurasjonsfil som vi kaller jndi.properties som ser slik ut: java.naming.factory.initial=com.sun.jndi.cosnaming.cnctxfactory java.naming.provider.url=iiop://th.idb.hist.no:1050 Sørg for å legge jndi.properties i samme katalog som klientprogrammet du lager. Skjelettet for dette programmet vil se slik ut: public static void main(string args[]){... Properties prop = new Properties(); prop.load(new FileInputStream("jndi.properties")); //Skriv ut en av verdiene i fila System.out.println(prop.getProperty("java.naming.factory.initial")); Context context = new InitialContext(prop);... } Vi bruker her et Properties-objekt (se leksjon 4). Dette objektet lastes med de verdiene vi ønsker via metoden load(). Denne metoden tar den fila vi ønsker å bruke som argument (her jndi.properties). Når vi oppretter context en (siste linje) så gir vi med Properties-objektet som argument slik at context en blir opprettet i henhold til våre ønsker angitt i jndi.properties.. 16

4.3 Distribuerte navne-/katalogtjenster Den som leste nøye i boka kunne konstantere at en navne/katalogtjenste kan være distribuert. Dette innebærer at man kanskje må via flere tjenere for å finne det objektet man er ute etter. DNS (Domain Name System) er et glimrende eksempel på dette. DNS brukes til å finne ressurser på Internett. Et typisk eksempel er at en bruker tar opp nettleseren sin og skriver inn URL en http://aitel.hist.no/fag/j2e/index.php. Brukeren vil da forvente at web-siden til dette faget dukker opp i nettleseren. For at dette skal skje må nettleseren først finne ut IP-nummeret til tjeneren aitel.hist.no som har ressursen vi er ute etter. For å få dette IP-nummeret så spør nettleseren en DNS-tjener. Denne tjeneren vil ha en oversikt over hvilket IP-nummer ulike maskiner har. Dette blir veldig likt om du skulle ringe meg. Du vet jeg heter Tomas Holt, men du vet ikke telefonnummeret mitt. For å få tak i dette ringer du opplysningen som gir deg nummeret mitt. Du vil da være i stand til å kontakte meg. DNS består dog ikke av en tjener. Ingen enkelt tjener har oversikt over alle maskinene på Internett. Hver organisasjon har sin egen DNS-tjener. For å føre eksemplet over litt lenger så la oss si at du studerer ved NTNU og sitter på deres datasal. For å få se web-siden til dette faget kan følgende skje (det kan også løses på en annen måte): Root Lag 1 COM DNS ORG DNS 2 NO DNS andre domener Lag 2 3 1 Nettleser 6 NTNU DNS 4 5 HIST DNS AITEL DNS Lag 3 Lag 4 7 AITeL's maskiner Web-tjener: /fag/index.php Forklaring til figur: 1) Nettleser spør DNS-tjeneren i det miljøet den befinner seg i om adressen til tjeneren aitel.hist.no. (Nettleseren får adressen til denne tjeneren via operativsystemet. Hvordan dette settes opp kan være forskjellig. Det kan gjøres automatisk, noe som er typisk 17

hvis du bruker Windows mot en Internett tilbyder (ISP), evt. kan dette settes opp manuelt). 2) NTNU s DNS-tjener på Lag 3 vet ikke hvilket IP-nummer denne tjeneren har så den går til toppen av DNS-hierarkiet og spør root DNS-tjener på Lag 1. Denne tjeneren (det kan være flere like root tjenere og hvilken som forespøres kan være tilfeldig) har oversikt over alle DNS-tjenerne som ligger på Lag 2 (mao. den vet av minst en tjener som er sjef over NO-domenet, en for COM-domenet, en for ORG-domenet osv). Ettersom adressen vi bruker slutter med.no så er dette en jobb for DNS-tjeneren i NOdomenet. Adressen til denne tjeneren blir derfor returnert. 3) Det sendes nå en forespørsel om å få adressen til aitel.hist.no til NO-tjeneren. Denne har imidlertid kun oversikt over DNS-tjenerne som ligger på nivået under NO-tjeneren (Lag 3). NO-tjeneren har derfor adressen til ntnu.no og hist.no, men ikke aitel.hist.no (pga. at dette blir to nivå ned). Adressen til HIST s DNS-tjener returneres. 4) Det sendes en forespørsel til HIST sin DNS-tjener om å få adressen til aitel.hist.no. Denne har imidlertid heller ikke adressen, men vet om AITeL s DNS-tjener som ligger på laget under. Adressen til denne returneres derfor. 5) Det sendes en forespørsel til AITeL sin DNS-tjener. Denne har oversikt over alle maskiner som finnes i AITeL (dvs. alle maskiner med domenenavnet aitel.hist.no, f.eks. maskin1.aitel.hist.no osv) I dette tilfellet er det ikke spesifisert hvilken maskin man ønsker innenfor AITEL, og denne tjeneren returnerer da adressen til web-tjeneren (dette gjøres når det ikke er spesifisert en annen maskin). 6) Adressen returneres tilbake til nettleser 7) Nettleser bruker adressen til å kontakte ønsket Web-tjener og Web-tjeneren returnerer ønsket ressurs (/fag/index.php). Det du bør bite deg merke i her er at ingen DNS-tjener har oversikt over alle tjenerne på nett. For å finne adressen til en gitt maskin vil det (ofte) være samarbeid mellom flere DNStjenere. Systemet er altså distribuert. Løsningen er veldig viktig fordi den sørger for at ballasten kan spres på flere tjenere, og at ingen maskin faktisk trenger å lagre alle adresser. Merk også at det vil være enkelt å legge til en maskin ved AITeL. Hvis vi gir denne maskinen navnet ny.aitel.hist.no, så er alt man trenger å gjøre for at denne maskinen skal være tilgjengelig for alle maskiner i verden (tilknyttet Internett), å legge til denne maskinen i DNStjeneren til AITeL. Alle forespørsler om IP-nummeret til ny.aitel.hist.no vil gå via AITeL sin DNS-tjener. Merk også at man ved AITeL vil ha minst to DNS-tjenere, den ene replikerer den andre (mao. den har samme innhold). Grunnen til dette er at hvis den ene skulle krasje så skal man fortsatt ha en operativ DNS-tjener. Her er det vanlig at man har en hoventjener (master). Endringer i adresser skjer i denne, og så vil den andre tjeneren (slaven) med jevne mellomrom hente oppdateringer fra hovedtjeneren. For mer informasjon om DNS se http://www.howstuffworks.com/dns.htm Andre navne-/katalogtjenester kan ha liknende distribuerte løsninger. Merk imidlertid at klienten ikke nødvendigvis vil ha noen formening om navne-/katalogtjenesten er distribuert eller ikke. 18

4.4 Innleveringsoppgave Kapittel 7.4 i boka går igjennom hvordan man kan bruke JNDI i forbindelse med navne- /katalogtjenester. Et begrep som er viktig her er en context. En navne-/katalogtjeneste kan bestå av et hierarki. Et glimrende eksempel på dette er DNS (se tidligere kapittel). Filsystemet er et annet eksempel. Her har du typisk en katalog som heter c:\. Denne katalogen kan sees på som en context som inneholder andre kataloger (kontekst) og filer. Katalogen c:\temp \ er altså en subcontext til c:\. Du kan som tidligere beskrevet bruke JNDI mot blant annet DNS og filsystemet. Koden under viser deler av koden som skal til for å bruke JNDI mot filsystemet (koden er også vedlagt). Oppgaven din blir å lage inneholdet i metoden skrivutinnholdicontext() slik at innholdet i en bestemt katalog skrives ut. Sørg også for å skrive ut innholdet i en av underkatalogene (subcontext) til denne katalogen (det er det som skjer ved andre kall til skrivutinnholdicontext()). Løsningen din må altså gjøre lookup(), list() eller listbindings() på konteksten (list er kanskje det mest hensiktsmessige, se API-dokumentasjonen). Se APIdokumentasjonen for nærmere beskrivelse av de ulike metodene. Merk deg koden i uthevet skrift under. I Context-klassen finner du en del ferdigdefinerte strenger. Java-strengen Context.INITIAL_CONTEXT_FACTORY har verdien java.naming.factory.initial. Resultatet vil altså være det samme uansett om vi bruker eller env.setproperty(context.initial_context_factory, "com.sun.jndi.fscontext.fscontextfactory"); env.setproperty("java.naming.factory.initial", " com.sun.jndi.fscontext.fscontextfactory "); Det vil imidlertid være en fordel å bruke førstnevnte når vi kan fordi dette er et variabelnavn. Vi vil derfor få kompileringsfeil hvis vi skriver feil, f.eks. Cntxto.INITIAL_CONTEXT_FACTORY, Bruker vi den siste linjen vil vi ikke få kompileringsfeil om vi skriver feil, noe som vil resultere i feil under kjøring av koden (vi vil etter all sannsynlighet ikke finne driveren). 19

import javax.naming.*; import java.util.*; import javax.swing.*; public class Oving7 { public static void main(string[] args) throws Exception { Properties miljø = new Properties(); miljø.setproperty(context.initial_context_factory, "com.sun.jndi.fscontext.fscontextfactory"); String kontekstnavn = "file:/"; String navn1 = JOptionPane.showInputDialog("Oppgi navn på katalog på 1.nivå: "); kontekstnavn += navn1; miljø.setproperty(context.provider_url, kontekstnavn); Context kontekst = new InitialContext(miljø); System.out.println("\nInnhold i katalogen " + kontekstnavn + ":"); skrivutinnholdicontext(kontekst); String navn2 = JOptionPane.showInputDialog("Oppgi navn på katalog på 2.nivå: "); kontekstnavn += "/" + navn2; miljø.setproperty(context.provider_url, kontekstnavn); kontekst = new InitialContext(miljø); System.out.println("\nInnhold i katalogen " + kontekstnavn + ":"); skrivutinnholdicontext(kontekst); System.exit(0); } public static void skrivutinnholdicontext(context kontekst) throws NamingException { //fyll inn her => start med lookup(), list() eller listbindings()... //skriv så ut innholdet i valgt katalog } } } Husk at når du skal bruke JNDI mot filsystemet så må du ha driveren (Service Provider) for filsystemet (se kapittel 4.1). Filen denne ligger i heter fscontext.jar. Denne filen må altså finnes i classpath for at programmet ditt skal fungere. 20

5 Lenker brukt i leksjonen http://java.sun.com http://www.howstuffworks.com/dns.htm 6 Oppgaver 1) Tenk deg at jeg gir deg en J2EE-applikasjon (i en ear-fil). Beskriv i hovedtrekk hva som skal til for å teste denne applikasjonen. Beskriv hvilke verktøy og kommandoer du må bruke for å kjøre tjener/applikasjon/klient. 2) Rmiregistret er en navnetjeneste. Hva er oppgaven til denne navnetjenesten? 3) Rmiregistret er ikke en distribuert navnetjeneste (den må ligge på en maskin). DNS er en navnetjeneste som er distribuert. Hva innebærer dette og hvilke fordeler kan dette ha? 4) Gjør oppgaven beskrevet i kapittel 4.4 21