Avatar billede kkaen Nybegynder
31. maj 2010 - 14:04 Der er 60 kommentarer og
1 løsning

Opsætning af TomCat

Jeg har et website, som jeg gerne vil udgive på en intern server.
På serveren er der installeret TomCat. Websitet benytter diverse packages, nogle servletter samt en database.

Jeg har udgivet servletterne og packages i "...TomCat 6.0\lib\", og database-adgangen er forsøgt checket. Den er sat op med de samme portnumre som i udviklingsprojektet. Eneste forskel er login til administratoren. Men dette burde vel ikke have indflydelse på brug af databasen?

Når jeg forsøger at tilgå jsp-siderne gennen browseren, så får jeg meddelelsen:
org.apache.jasper.JasperException: An exception occoured processing JSP page pagename.jsp at line 129.

På linie 129 er der database-adgang, da et resultset tilgås gennem rs.next().

Videre i fejlmeddelelsen står der:
java.lang.NullPointerException
org.apache.projektNavn.fil.jsp._jspService(linienummer)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
og så nogle flere org.apache.jasper-exceptions.

Det er servletterne, som står for database-adgangen. Jeg har forsøgt at gøre serveletterne tilgængelige ved at kopiere dem ud i "...Tomcat 6.0\lib\PackageName\". Jeg går ud fra, at det er disse serveletter, som er årsagen til fejlene.

Men hvordan kan jeg rette fejlene?
Avatar billede kkaen Nybegynder
31. maj 2010 - 15:00 #1
Jeg udvikler i Netbeans 6.8. Kan det være, at servletterne skal opsættes inde i projektets /WEB-INF/web.xml ?
Det har jeg forsøgt at sætte op nu, med det giver exceptions:

Line 29 Column 23 -- cvc-complex-type.2.4.b: The content of element 'servlet-mapping' is not complete. One of '{"http://java.sun.com/xml/ns/javaee":url-pattern}' is expected.
java.io.IOException: org.xml.sax.SAXParseException: cvc-complex-type.2.4.b: The content of element 'servlet-mapping' is not complete. One of '{"http://java.sun.com/xml/ns/javaee":url-pattern}' is expected.

Hvordan sættes disse værdier korrekt op?
Avatar billede arne_v Ekspert
31. maj 2010 - 16:03 #2
Jeg vil klart anbefale at du producerer war filer og så deployer dem til produktions serveren.

Det der med IDE'er som går direkte i server træet er noget rod.

Ja - servlets skal defineres i web.xml.

Hvis du poster din web.xml så kan vi sikkert hurtigt se hvad problemet er.
Avatar billede arne_v Ekspert
31. maj 2010 - 16:52 #3
Syntaxen for at definere servlets i web.xml er:

...
    <servlet>
        <servlet-name>DitLogiskeServletNavn</servlet-name>
        <servlet-class>dinpakke.DinKlasse</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DitLogiskeServletNavn</servlet-name>
        <url-pattern>/DetEksterneNavn</url-pattern>
    </servlet-mapping>
...

den vil få:

http://server/dinwebapp/DetEksterneNavn

til at køre dinpakke.DinKlasse
Avatar billede kkaen Nybegynder
31. maj 2010 - 17:13 #4
Ja, det var også en løsning med WAR, jeg forsøgte med først. Men eftersom jeg ikke kunne få det sat rigtigt op, gik jeg tilbage til den gammeldags metode.

Det var også web.xml, jeg konkluderede, var det springene punkt. Jeg kunne bare ikke finde nogen syntax-definition umiddelbart. Jeg fandt dog 2 artikler online, som forklarede lidt om det.

Jeg har desværre ikke adgang til web.xml-filen p.t., men engang i morgen får jeg set på det :-)
Avatar billede kkaen Nybegynder
01. juni 2010 - 08:58 #5
Så, nu har jeg fået set på web.xml, og rettet lidt i den. Nu ser den således ud:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>ServletDatabase</servlet-name>
        <servlet-class>ServletPackage.ServletDatabase</servlet-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </servlet>
    <servlet>
        <servlet-name>DatabaseHandler</servlet-name>
        <servlet-class>ServletPackage.DatabaseHandler</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ServletDatabaseProcess</servlet-name>
        <servlet-class>ServletPackage.ServletDatabaseProcess</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ServletDatabaseReceiveData</servlet-name>
        <servlet-class>ServletPackage.ServletDatabaseReceiveData</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ServletDatabaseTeacher</servlet-name>
        <servlet-class>ServletPackage.ServletDatabaseTeacher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DatabaseHandler</servlet-name>
        <url-pattern>/DatabaseHandler</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletDatabaseProcess</servlet-name>
        <url-pattern>/ServletDatabaseProcess</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletDatabaseReceiveData</servlet-name>
        <url-pattern>/ServletDatabaseReceiveData</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletDatabaseTeacher</servlet-name>
        <url-pattern>/ServletDatabaseTeacher</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletDatabase</servlet-name>
        <url-pattern>/ServletDatabase</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <resource-ref>
        <res-ref-name>javax.sql.DataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
    <resource-ref>
        <res-ref-name>javax.jms.ConnectionFactory</res-ref-name>
        <res-type>javax.jms.ConnectionFactory</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
    <resource-ref>
        <res-ref-name>javax.mail.Session</res-ref-name>
        <res-type>javax.mail.Session</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
    <resource-ref>
        <res-ref-name>java.net.URL</res-ref-name>
        <res-type>java.net.URL</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
</web-app>

Så har jeg genbygget server.web, og uploaded den til serveren. Men hvordan angives war-filen inde i tomcat, så den virker? Det er dette trin, jeg har fundet nogle artikler om...jeg ser lige på dem.
Avatar billede kkaen Nybegynder
01. juni 2010 - 09:10 #6
Det primære link, jeg fandt i går, er:

http://supportweb.cs.bham.ac.uk/documentation/java/servlets/netbeans-webapps/

som også linker til:

http://supportweb.cs.bham.ac.uk/documentation/java/servlets/socs-tomcat/#id213976

Det ser ud som om, det vist ikke så let med tomcat endda. Og så skal der bruges noget, der hedder "SSH" til at opnå forbindelse til TomCat - kan det nu også passe?
Avatar billede kkaen Nybegynder
01. juni 2010 - 09:12 #7
Skal man bruge Ant til at deploy'e med?
Avatar billede arne_v Ekspert
01. juni 2010 - 15:12 #8
Faar du stadig fejl i linie 29 i web.xml med den postede?
Avatar billede arne_v Ekspert
01. juni 2010 - 15:12 #9
Det er nemt at deploye til Tomcat.

war filen skal bare kopieres til webapps dir.

I default opsaetning altsaa.
Avatar billede arne_v Ekspert
01. juni 2010 - 15:13 #10
ant er et glimrende tool ogsaa til den kopiering.
Avatar billede kkaen Nybegynder
01. juni 2010 - 15:56 #11
Jeg går ud fra, at jeg ikke behøver Ant til denne process. Jeg skal blot være helt klar over hvert trin i processen.

Hmm, jeg kan ikke lige erindre, hvor fejlen nu opstod (jeg sidder ikke ved computeren mere i dag).

"war filen skal bare kopieres til webapps dir."
-> er det så til "webapps", til "ROOT" eller til projektnavns-dir? Jeg har prøvet alle sammen bortset fra projektnavns-dir.
Faktisk er det lykkedes mig, at uploade war-filen, og så få Tomcat til at pakke den ud, så det nu ligger i "webapps\projektnavn".

Det sidste skridt jeg er kommet til er, at det formentlig er databasen, som ikke er sat rigtig op så. Jeg har en mysql-connector.jar, som jeg har lagt ind i /lib. Så har jeg lige været ved at foretage en hel masse tilføjelser til server.xml, som jeg fandt på en netside (som jeg naturligvis ikke husker url'en på p.t.). Men det gav stadig fejl i tilgangen til ressourcerne - servletter eller databasen.
Avatar billede kkaen Nybegynder
01. juni 2010 - 15:57 #12
Jeg ville godt, hvis jeg kunne teste mysql-forbindelsen gennem en browser. Jeg har testet den gennem MySqlAdministrator, og her virker det fint.
Avatar billede arne_v Ekspert
01. juni 2010 - 16:03 #13
ant er kun convenience - COPY/cp/diverse filemanagers virker fint.
Avatar billede arne_v Ekspert
01. juni 2010 - 16:04 #14
Med en normal opsaetnings saa kopieres war fil til

$TOMCAT_ROOT/webapps

saa udpakker Tomcat den selv til:

$TOMCAT_ROOT/webapps/navnpaawarfil
Avatar billede arne_v Ekspert
01. juni 2010 - 16:07 #15
Uden connection pool (meget smaa apps):
- JDBC driver jar fil i web apps WEB-INF/lib
- lav connection naar skal bruges

Med connection pool (rigtige apps):
- JDBC driver i server lib
- connection pool defineret i konfiguration (flere muligheder)
- hent connection fra pool via DataSource
Avatar billede kkaen Nybegynder
02. juni 2010 - 09:09 #16
Jeg er mest opsat på ConnectionPool - men det er ikke det primære lige nu. Med mindre altså det er nødvendigt, for at applikationen kan testes. Ellers er første skridt, at applikationen virker på serveren. Så må tilretningerne/finpudsningerne komme bagefter.

Som jeg ser problemet p.t., så skal netsiderne sættes rigtigt om inde i server.xml, og så skal TomCat give adgang til MySql-databasen. Alle mine netsider benytter databasen, så hvis database-adgangen ikke virker, så kommer der fejl på netsiderne hver gang.

Det, jeg skrev om i går, som jeg havde tilføjet ud fra en vejledning på en netside (formentligt på http://oreilly.com/) er det der står inde i <inserted manually>-området. Hele <context>-afsnittet er det, jeg har tilføjet i server.xml overhovedet:

<Context path="/Server"
    docBase="webapps/Server.war"
    defaultSeesionTimeOut="30" isWAREExpanded="false"
    isWARValidated="false" isInvokerEnabled="true"
    isWorkDirPersistent="false" debug="0"
    reloadable="true" >

<!--inserted manually BEGIN -->   
    <Resource name="jdbc/MySQLDB"
        auth="Container"
        type="javax.sql.DataSource"/>

    <ResourceParams name="jdbc/MySQLDB"
        <parameter>
              <name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
        </parameter>
    <parameter>
        <name>maxActive</name>
        <value>10</value>
    </parameter>

    <parameter>
        <name>maxIdle</name>
        <value>5</value>
    </parameter>

    <parameter>
        <name>validationQuery</name>
        <value>SELECT 1</value>
    </parameter>

    <parameter>
        <name>testOnBorrow</name>
        <value>true</value>
    </parameter>
        <parameter>
        <name>timeBetweenEvictionRunsMillis</name>
        <value>10000</value>
    </parameter>
   
    <parameter>
        <name>minEvictableIdleTimeMillis</name>
        <value>60000</value>
    </parameter>
   
    <parameter>
        <name>username</name>
        <value>root</value>
    </parameter>
   
    <parameter>
        <name>password</name>
        <value>kode</value>
    </parameter>

    <parameter>
        <name>driverClassName</name>
        <value>com.mysql.jdbc.Driver</value>
    <parameter>
   
    <parameter>
        <name>localhost:8080</name>
        <value>jdbc:mysql://localhost:3306/</value>
    </parameter>
    </ResourceParams>
<!--inserted manually END -->
</Context>
Avatar billede kkaen Nybegynder
02. juni 2010 - 10:38 #17
TomCat kunne ikke engang startes op her til morgen. Jeg har udkommenteret det i <!--inserted manually-->, og nu kan TomCat køre igen.

Fejlen, jeg får, når jeg forsøger at tilgå jsp-siden gennem browseren er:

HTTP Status 500-

description: The server encountered an internal error()

Exception:
org.apache.jasper.JasperException: java.lang.NullPointerException
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java: 491)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Root cause
java.lang.NullPointerException
org.apache.jsp.jspFile_jsp._jspService(jspFile_jsp.java:190)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
org.apache.jasper.servlet.JspServlet.serviceJspFile(Jspservlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Avatar billede kkaen Nybegynder
02. juni 2010 - 11:00 #18
Der står forresten på
http://supportweb.cs.bham.ac.uk/documentation/java/servlets/netbeans-webapps/
at projektet skal laves inde i et WebModule. Dette har jeg ikke gjort. Er dette et problem? Og skal der rettes op på det, for at jsp-siderne kan findes? (det tyder umiddelbart på, at jsp-siderne godt kan findes gennem browseren, men at databasen udgør problemet)
Avatar billede kkaen Nybegynder
02. juni 2010 - 13:25 #19
Jeg har lige læst i en guide:

create a new class named HelloServlet in the directory WEB-INF/src

Jeg går ud fra, at det er under mappen "Web Pages".

Men mine servletter ligger under "Web Pages/Source Packages/servletPackage.ServletName"

Kan dette være en medvirkende årsag til problem-stillingen?
Avatar billede kkaen Nybegynder
02. juni 2010 - 13:56 #21
Beklager jeg næsten er ved at spamme denne post til, men jeg finder del-løsninger en masse steder.

Sidste del-løsning har jeg fundet på:
http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#JDBCRealm
Under QuickStart:
2:
Configure a database username and password for use by Tomcat, that has at least read only access to the tables described above. (Tomcat will never attempt to write to these tables.)

Vil det sige, at der skal oprettes en bruger-konto i TomCat, som står for (og har adgang til) læsning og skrivning til databasen?
Og så udføre det, der står under "Realm Element Attributes" efterfølgende?
Avatar billede arne_v Ekspert
02. juni 2010 - 16:45 #22
Connection pool i Tomcat er faktisk ret nemt.

Men det virker enormt svaert fordi:
1) der er maneg forskellige maader at goere det paa
2) Tomcat folkene er elendige til at skrive dokumentation
Avatar billede arne_v Ekspert
02. juni 2010 - 16:46 #23
For at lave en connection pool i en Tomcat 6.0 foeler man vejledningen her:

http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#JDBC%20Data%20Sources
Avatar billede arne_v Ekspert
02. juni 2010 - 16:48 #24
Eksempel:

put MySQL JDBC driver jar i lib

conf/context.xml tilfoej:

  <Resource name="jdbc/TestMySQL"
            auth="Container"
            type="javax.sql.DataSource"
            username=""
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/Test"
            maxActive="50"
            maxIdle="10"/>

webapps/xxxx/WEB-INF/web.xml tilfoej:

  <resource-ref>
    <res-ref-name>jdbc/TestMySQL</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

og naar koden skal bruge en connection saa:

    Context init = new InitialContext();
    Context ctx = (Context) init.lookup("java:comp/env");
    DataSource ds = (DataSource) ctx.lookup("jdbc/TestMySQL");
    Connection con = ds.getConnection();
Avatar billede arne_v Ekspert
02. juni 2010 - 16:49 #25
Det er ikke saa vanskeligt.

:-)
Avatar billede arne_v Ekspert
02. juni 2010 - 16:50 #26
Realm skal du bruge hvis du skal bruge container managed security d.v.s. at du i web.xml beder Tomcat beskytte dine sider og kraeve login med brugere i en database.
Avatar billede arne_v Ekspert
02. juni 2010 - 16:52 #27
Jeg skrev engang noget om det her:

http://www.eksperten.dk/guide/50

(den er dog skrevet til Tomcat 5.0, saa der kan vaere smaa aendringer)
Avatar billede kkaen Nybegynder
03. juni 2010 - 09:46 #28
02. juni 2010 kl. 16:48:48| #24

Det ser jo let og ligetil ud.

Jeg har dog længe tænkt på følgende problematik:
Når jeg nu udvikler i Netbeans, som ikke umiddelbart har adgang til den virkelige server, men opretter en manuel forbindelse til en lokal mysql-server, så kan omtalte connection-pool vel ikke virke? Eller kan man oprette en lokal connection-pool-forbindelse med de samme indstillinger, som så løser problemet? Eller bliver man nødt til manuelt at ændre sin kode, så når applikationen skal deploy'es, så skifer man database-adgangs-koden ud med connection-pool'en?
Avatar billede kkaen Nybegynder
03. juni 2010 - 09:47 #29
Hov, hvorfor blev mit indlæg sat ind som svar? Det plejer de da ikke, med mindre man manuelt sætter dem til det...
Avatar billede kkaen Nybegynder
03. juni 2010 - 10:21 #30
Nu har jeg prøvet, at implementere connection-pooling i java-koden. Men jeg har ændret lidt i det, for at compileren ville acceptere det. Ser det rigtigt ud?
Nu brokker den sig over "lookup("");" - metoden findes slet ikke, hvis jeg bruger intellisence. Har jeg misforstået noget?

InitialContext init=new InitialContext();
Context ctx=(Context)init.lookup("java:comp/env");
DataSource ds=(DataSource)ctx.lookup("jdbc/TestMySQL");
Connection connection=ds.getConnection();
Avatar billede kkaen Nybegynder
03. juni 2010 - 10:23 #31
(DataSource)ctx.lookup("jdbc/TestMySQL");
that is...
Avatar billede kkaen Nybegynder
03. juni 2010 - 13:12 #32
Opdate:

Yeyh, nu har jeg vist fået noget lignende til at virke. Jeg har fulgt vejledningen:

http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html

under afsnittet "MySQL DBCP Example"
Og jeg tror, jeg er med på sammenhængen. Der er dog 1 lille ting, som jeg ikke helt kan finde ud af, og heller ikke kan finde dokumentation på nogle steder. Problemet er inde i server.xml i <Context> under <Resource name="jdbc/TestDB"...>

Selve "TestDB" kan jeg ikke finde ud af, hvorfor det skal stå der. Den eneste forklaring, jeg kan finde, er, at det er det viruelle navn for connection-poolingen, som skal benyttes i koden, hvor der skal kaldes forbindelser til databasen. Her jeg fat i den lange ende?

PS: Eneste problem, jeg havde i processen, var, at jsp-siden ikke kunne finde uri="http://java.sun.com/jsp/jstl/sql" prefix="sql". Derfor fandt jeg filen (filerne) online, downloadede dem, og lagde dem ind i tomcat/lib, hvorefter det virkede.
Avatar billede arne_v Ekspert
03. juni 2010 - 15:36 #33
Hvis du ikke har meget adgang til serveren, saa kan du maaske ikke rette i conf/context.xml, men du kan ogsaa putte den i din web applikation i META-INF/context.xml !

Jeg foretraekker normalt at database connection pool er en server config ting og ikke en app development ting, men man maa jo bruge det som virker.
Avatar billede arne_v Ekspert
03. juni 2010 - 15:37 #34
Hvilket navn du bruger er ligegyldigt.

Det skal bare vaere samme navn alle 3 steder:
- context.xml
- web.xml
- Java koden
Avatar billede kkaen Nybegynder
03. juni 2010 - 19:47 #35
"men du kan ogsaa putte den i din web applikation i META-INF/context.xml !"
-> jeg er ikke sikker på, at jeg har adgang til serveren på compilerings-tidspunktet. I så fald bliver jeg nødt til at have en lokal "server" i Netbeans. Det har hidtil været Glassfish. Hvis man skal opsætte forbindelseskode forskelligt i henhold til server-type, så duer forbindelses-koden jo ikke både lokalt og på deployment-server (men connection-pooling-forbindelsen er vel den samme, uanset hvilken server-type, der er tale om...).
Dette burde vel kunne lade sig gøre, så jeg ikke behøver oprette manuel forbindelse til databasen på lokalt udviklings-trin og connection-pooling på deployment-trin?

"Hvilket navn du bruger er ligegyldigt."
-> jeg antager stadig, at det er connection-pooling-navn, der er tale om her?
Avatar billede arne_v Ekspert
03. juni 2010 - 20:14 #36
META-INF/context.xml i din war fil, saa vil Tomcat haandtere den ved deployment.

Du kan ogsaa godt opsaette en connection pool i Glassfish. web.xml og Java koden er den samme. Du skal bruge noget andet en context.xml men Glassfish ignorerer formentligt den, saa du behoever ikke have to builds.

Ja. Navn paa connection pool data source.
Avatar billede kkaen Nybegynder
03. juni 2010 - 22:58 #37
Kan man også angive connection-pool i META-INF/contect.xml? Det vil jeg lige prøve at finde nogle eksempler på implementeringen af så...
Avatar billede arne_v Ekspert
04. juni 2010 - 03:43 #38
Ja.
Avatar billede arne_v Ekspert
04. juni 2010 - 03:46 #39
En fil med:

<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <Resource name="jdbc/TestMySQL"
            auth="Container"
            type="javax.sql.DataSource"
            username=""
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/Test"
            maxActive="50"
            maxIdle="10"/>
</Context>

burde virke.
Avatar billede kkaen Nybegynder
04. juni 2010 - 12:22 #40
Jeg kan ikke finde nogen fil af navnet "META-INF/contect.xml" inde i mit projekt. Jeg har søgt efter information omkring det, og tilsyneladende er "WEB-INF/web.xml" det samme.

Så den fil har jeg forsøgt at ændre diverse i. Men uden held.
Ud over dit eksempel med:

<Resource name="jdbc/TestMySQL"
            auth="Container"
            type="javax.sql.DataSource"
            username=""
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/DatabaseNavn"
            maxActive="50"
            maxIdle="10"/>

Så har jeg forsøgt at implementere eksempler fra:
http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/datasource.html

http://dev.mysql.com/tech-resources/articles/connection_pooling_with_connectorj.html

http://www.chariotsolutions.com/geronimo/geronimo-1.1/database-mapping.html

http://www.codeweblog.com/java-comp-env-jdbc-datasource-and-jdbc-datasource-not/

http://www.javalobby.org/java/forums/t90484.html

Men uanset hvad jeg gør, så kommer der fejl. Tilsyneladende er det ved det trin, hvor selve database-navnet bliver forbundet med det virtuelle ressource-navn.

Jeg vil tro, at jeg er ret tæt på målet. Men noget grundlæggende er forkert et sted...?
Avatar billede arne_v Ekspert
04. juni 2010 - 15:25 #41
Det er en ny fil som du selv skal lave !
Avatar billede kkaen Nybegynder
07. juni 2010 - 10:49 #42
Jeg har nu brugt en 4 timer på at forsøge mig frem til en kørbar løsning. Men uden held.
Så det er vist lettest, hvis jeg benytter en lokal TomCat. Derfor har jeg installeret en lokal TomCat-server også. Jeg kan også godt starte den op inde i Netbeans under Service-fanen, og se netside-eksempler. Problemet er blot, at når jeg forsøger at køre min applikation i Netbeans, så starter den Glassfish op. Derfor har jeg slettet Glassfish-serveren i Netbeans. Nu står der blot "Missing server", og når jeg forsøger at benytte "Resolve missing server-problem" under projektnavns-tagget, så er der ingen Java EE 6  servere. Når jeg forsøger at oprette en TomCat 6 i den dialogboks, og jeg når igennem opsætningen, så kommer der stadig ikke nogen linie frem i "Available Java EE 6 compatible servers", og jeg kan derfor ikke komme videre i processen. Hvordan får jeg skabt denne server-instans inde i Netbeans, så jeg kan benytte TomCat?
Avatar billede kkaen Nybegynder
08. juni 2010 - 09:58 #43
Eftersom jeg ikke kunne komme længere med lokal oprettelse af TomCat, er jeg gået tilbage til at builde på klienten, uploade til serveren, og teste på den måde. Så ser jeg i log-filerne efter output.

Og det undrer mig nu en del, hvorfor der i log-filen står:

DatabaseHandler->Attempting to create database...
DatabaseHandler->ExceptionConstructor= java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
Access denied for user 'root'@'localhost' (using password: NO)
ServletDatabase->doDatabaseConnectionInitialization:Exceptionnull
BEGIN connectionPool for MySql connection...
DatabaseHandler->ExceptionConstructor= javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
Name jdbc is not bound in this Context
ServletDatabase->doDatabaseConnectionInitialization:Exceptionnull

Når jeg i server.xml har skrevet:


<Context path="/Server" docBase="Server.war" defaultSeesionTimeOut="30" isWAREExpanded="false" isWARValidated="false" isInvokerEnabled="true" isWorkDirPersistent="false" debug="0" reloadable="true" crossContext="true">
  <Resource name="jdbc/MySQLDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="clientUser" password="code" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/databaseNavn" />
</Context>

Giver dette overhovedet noget mening, eller er det simpelthen forbindelsen til connectionPool'en, som ikke er sat rigtigt op?
Avatar billede arne_v Ekspert
09. juni 2010 - 04:24 #44
Jeg ville bygge en war fil i NetBeans og så deploye den til Tomcat.
Avatar billede arne_v Ekspert
09. juni 2010 - 04:26 #45
De linier i log filen ligner noget far din kode.

Hvordan ser DatabaseHandler og ServletDatabase ud?
Avatar billede kkaen Nybegynder
09. juni 2010 - 10:36 #46
Ja, jeg har også benyttet war til deployment. Det gør det en del lettere. Her til morgen har jeg (igen igen) været ved at gennemsøge nettet efter mulige løsninger. Jeg har da også fundet lidt, som jeg har forsøgt at tage det interessante fra. Men altså vi snakker om en udskiftning af 20 linier kode, og +- 50 liniers kode ved siden af (til metoder f.eks.). Det interessante er så, at hidtil har war-filen fyldt en 60 MB. Og pludselig efter tilretningerne fylder den kun 15 MB. Det ser da mærkeligt ud. Og jsp-filerne ligger rigtigt nok deri, så måske er det nogle grafik-filer, som pludselig ikke er inkluderet i buildet.

Nå, men DatabaseHandler står blot for selve forbindelsen til databasen med tilhørende insert/update/delete-statements. Og så kan den returnere nogle resultsets.
ServletDatabase initialiserer DatabaseHandleren, og kan derved tilbyde de funktioner gennem nettet, som DatabaseHandleren stiller til rådighed.

Tekst i logfilerne er bl.a. System.out.println() fra min kode, så jeg kan følge lidt med i, hvad der sker under kørsel.
Jeg har nu ryttet gevaldigt op i server.xml, så den kun indeholder det mest grundlæggende (ligesom i det connectionPool-eksempel, jeg rent faktisk fik til at køre, men som blot var med test-database, og initialisering direkte fra jsp-siden).

Nu ser min main-kode ud som følger:
...
  try {

    InitialContext context = createContext();

    String jndiName="jdbc/MySQLDB";

    connection=getConnection();
                       
    //Establishes a connection pool that contains connections:
    //ConnectionPoolDataSource dataSource2 = (ConnectionPoolDataSource) context.lookup(jndiName);
    //PooledConnection pooledConnection = dataSource2.getPooledConnection();

  } catch (Exception e) {
  System.out.println("SetupJNDIDataSource err: " + e.getMessage());
  e.printStackTrace();
}
                     
statement=connection.createStatement();

rs3 = statement.executeQuery("select * from....

Og metoder er:

private Connection getConnection()
    {
    Connection connection = null;
    try
    {
      InitialContext context = new InitialContext();
      DataSource dataSource = (DataSource) context.lookup("jdbc/MySQLDB");
      connection = dataSource.getConnection();
    } catch (NamingException e) {
      e.printStackTrace();
    } catch (SQLException e) {
    e.printStackTrace();
  }
  return connection;
}

private static InitialContext createContext() throws NamingException {
  Properties env = new Properties();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
  env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
  InitialContext context = new InitialContext(env);
  return context;
}

server.xml ser således ud:
<Context path="/Server" docBase="Server.war" debug="1" reloadable="true" crossContext="true">
  <Resource name="jdbc/MySQLDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="clientUser" password="kode" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/databaseNavn" />
</Context>

Og en logfil fra TomCat ("stdout..."):
if the page is NOT postback then this is initialized
Is beginning MySql-initialization...
DatabaseHandler->ds= org.apache.tomcat.dbcp.dbcp.BasicDataSource@55d93d
javax.naming.NoInitialContextException: Cannot instantiate class: oracle.jdbc.pool.OracleDataSourceFactory [Root exception is java.lang.ClassCastException: oracle.jdbc.pool.OracleDataSourceFactory cannot be cast to javax.naming.spi.InitialContextFactory]
END connectionPool for MySql connection...
DatabaseHandler->Database created!

ServeltDatabase->proceesrequest
doDatabaseConnectionInitialization() BEGIN
ServletDatabase->doDatabaseConnectionInitialization:Exceptionnull
doDatabaseConnectionInitialization() END
ServletDatabase->at the end of processRequest
Done initialization now...

DONE getAttribute("rs")

Det ses klart ud fra denne log, at problemerne er ved oprettelse af database-forbindelsen, og naturligvis alle de gange, hvor der foretages operationer på denne.
Jeg går ud fra, at fejlen blot er en mindre, men vital, del af database-initiliaseringen. Jeg kan blot ikke se, hvor fejlen er.
En af de få steder, hvor jeg ikke er helt med på forståelsen her til morgen er koden "env.put(Context.PROVIDER_URL, "rmi://localhost:1099");". Jeg har accepteret, at rmi åbenbart er en gyldig metode af bruge, men hvorfor der står localhost med portnummeret, er jeg ikke med på. Burde det ikke være det samme portnummer, som mysql stiller databasen til rådighed gennem? Altså 3306?

Al hjælp vil blive GEVALDIG påskønnet!
Avatar billede kkaen Nybegynder
09. juni 2010 - 11:01 #47
Ang. den ændrede størrelse på war-filen, så skyldes det formentligt, at der inde i projektet var en mappe af navnet "UploadedFiles". Heri var der gemt en masse filer, som kunne uploades gennem applikationen. Alle disse er væk nu (selvom det bestemt ikke er ønskværdigt). Jeg går ud fra, at dette er sket, når jeg trykker på "Build main project" inde i Netbeans, da jeg derved manuelt bygger war-filen. Så må jeg blot manuelt indsætte disse filer i mappen i TomCat, eller også må jeg finde nogle indstillinger i Netbeans, så disse filer ikke slettes.
Avatar billede kkaen Nybegynder
09. juni 2010 - 14:22 #48
Yeay, nu har jeg fulgt vejledningen på:
http://onjava.com/pub/a/onjava/2006/04/19/database-connection-pooling-with-tomcat.html

Og pludselig var der ikke flere fejlmeldinger i loggen. Så tog jeg udskrift i databaseHandleren af indholdet i resultset's, og der var den rigtige data. Så nu har jeg da fået forbindelse. Nu skal resten bare virke med videresending af resultsets bl.a..
Avatar billede arne_v Ekspert
10. juni 2010 - 04:27 #49
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
  env.put(Context.PROVIDER_URL, "rmi://localhost:1099");

burde ikke være nødvendig.

Tomcat burde selv finde de rigtieg værdier ved:
  new InitialContext();
Avatar billede arne_v Ekspert
10. juni 2010 - 04:31 #50
URL er ikke URL på databasen med URL på JNDI serveren.

Så det skal absolut ikke være samme port nummer som MySQL.

JNDI serveren er en service inden i Tomcat hvor man kan gemme et objekt under et navn og så kan man hente objektet på navn.

I dette tilfælde henter du connection poolen via et navn for at bede poolen give dig en connection.

Environment er nornalt kun nødvendig når man skal connecte fra Java kode som kører uden for serveren.

Det giver ikke mening at hente connection pool fra kode udenfor serveren, men der er andre typer objekter hvor det giver mening.

Environment er server specifik d.v.s. at Tomcat, JBoss, WebSphere, WebLogic etc. skal sættes op med forskellige værdier.
Avatar billede arne_v Ekspert
10. juni 2010 - 04:34 #51
Du bør have mulighed for at bede NetBeans inkludere alt det i war filen som du skal bruge.

Jeg tilhører årgang dinosaur og derfor gide jeg normalt slet ikke lade IDE lave den slags, men bruger ant til at bygge en war med.

Eksempel:

<project name="testrichfaces" default="deploy">
    <property name="war" value="testrichfaces.war"/>
    <property name="src" value="src"/>
    <property name="bin" value="bin"/>
    <property name="descrip" value="descrip"/>
    <property name="lib" value="lib"/>
    <property name="jsp" value="jsp"/>
    <property name="tomcatdeploy" value="C:/Jakarta/Tomcat-6.0.16/webapps"/>
    <target name="compile">
        <javac srcdir="${src}" destdir="${bin}"/>
    </target>
    <target name="build" depends="compile">
        <war warfile="${war}" webxml="${descrip}/web.xml">
            <classes dir="${bin}"/>
            <lib dir="${lib}"/>
            <fileset dir="${jsp}"/>
            <webinf dir="${descrip}" excludes="web.xml"/>
        </war>
    </target>
    <target name="deploy" depends="build">
        <copy file="${war}" todir="${tomcatdeploy}"/>
    </target>
</project>
Avatar billede kkaen Nybegynder
10. juni 2010 - 08:30 #52
Dinosaurer er også at foretrække - så ved man da, hvad man har med at gøre :-)

Nå, men jeg fik den mest simple jsp-side med database-adgang til at køre på tomcat med connectionpooling i går, så hvis du lige vil lægge et svar arne_v ?
Avatar billede arne_v Ekspert
10. juni 2010 - 15:11 #53
svar
Avatar billede kkaen Nybegynder
10. juni 2010 - 16:23 #54
Jeg har også fået den lidt mere komplicerede jsp-side til at køre i dag :-)
Avatar billede arne_v Ekspert
10. juni 2010 - 16:48 #55
Bruger du:
- JSF
- JSTL
- <% %>
?
Avatar billede kkaen Nybegynder
10. juni 2010 - 21:21 #56
Jeg bruger primært <%=%>
JSF ved jeg intet om.
JSTL har jeg vist ikke engang hørt om...
Avatar billede arne_v Ekspert
10. juni 2010 - 21:45 #57
JSTL og EL er to simple teknologier oven paa JSP som hjaelper til at undgaa for meget <% %> som jo ligner noget ASP eller PHP fra for 10 aar siden.
Avatar billede kkaen Nybegynder
10. juni 2010 - 22:31 #58
Det må jeg så nok hellere undersøge nærmere :-)
Avatar billede arne_v Ekspert
11. juni 2010 - 03:06 #59
Her er et eksempel.

The old way:


<%@ page import="java.util.*" %>
<%!
// test only - this class would be in its own bean for a real case
public class Data {
    private int f1;
    private String f2;
    public Data(int f1, String f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
    public int getF1() {
        return f1;
    }
    public void setF1(int f1) {
        this.f1 = f1;
    }
    public String getF2() {
        return f2;
    }
    public void setF2(String f2) {
        this.f2 = f2;
    }
}
%>
<%
// test only - these data would be loaded from a database for a real case
List lst = new ArrayList();
lst.add(new Data(1, "A"));
lst.add(new Data(2, "BB"));
lst.add(new Data(3, "CCC"));
%>
<!-- This is what we want to show: -->
<table border="1">
<tr>
<th>F1</th>
<th>F2</th>
</tr>
<%
for(int i = 0; i < lst.size(); i++) {
%>
<tr>
<td><%=((Data)lst.get(i)).getF1()%></td>
<td><%=((Data)lst.get(i)).getF2()%></td>
</tr>
<%
}
%>
</table>


The new way:


<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.*" %>
<%!
// test only - this class would be in its own bean for a real case
public class Data {
    private int f1;
    private String f2;
    public Data(int f1, String f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
    public int getF1() {
        return f1;
    }
    public void setF1(int f1) {
        this.f1 = f1;
    }
    public String getF2() {
        return f2;
    }
    public void setF2(String f2) {
        this.f2 = f2;
    }
}
%>
<%
// test only - these data would be loaded from a database for a real case
List lst = new ArrayList();
lst.add(new Data(1, "A"));
lst.add(new Data(2, "BB"));
lst.add(new Data(3, "CCC"));
request.setAttribute("lst", lst);
%>
<!-- This is what we want to show: -->
<table border="1">
<tr>
<th>F1</th>
<th>F2</th>
</tr>
<c:forEach var="o" items="${lst}">
<tr>
<td>${o.f1}</td>
<td>${o.f2}</td>
</tr>
</c:forEach>
</table>
Avatar billede kkaen Nybegynder
11. juni 2010 - 09:37 #60
Tjo, men det ser da meget ens ud. For mig at se, så er forskellen umiddelbart kun, at <%%> udskiftes med ${} samt at "forEach" kan bruges. Det vil sige, at man skal sætte sig ind i en ny teknologi, blot for at lave koden en lille smule mere fancy. Altså koden bliver lidt mere kompliceret for uforstående ift. teknologien (lidt alle c++ hvis man kun kender c), men det virkelige vundne har jeg svært ved at se...? (måske bliver der mindre at holde styr på (selvom det vist er minimalt) - til gengæld skal man så holde styr på en ny teknologi.)
Avatar billede kkaen Nybegynder
11. juni 2010 - 09:38 #61
Rettelse:
"JSTL har jeg vist ikke engang hørt om... "
jo, det har jeg. Jeg har blot ikke fået det til at virke i nyere tid...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester