mit JSF richtig layouten

Status
Nicht offen für weitere Antworten.

Gumble

Bekanntes Mitglied
Hi there,
ich wurschtel gerade mal wieder an meiner ungeliebten Weboberflaeche rum und so langsam nervt das auch gewaltig. Vor allem wird der Code nicht leserlich und das Design auesserst haesslich :(
Kann mir jemand paar schicke Beispiele geben/zeigen bei dem das Layout schick geloest wurde? will gern ein Header haben, dass entweder Einlogfelder (username/passwort) oder ein Ausloglink und eine Userinfo (=username) hat. Ein Menue auf der linken Seite (fuer JSF-Navi) und noch ein Footer. CSS soll auch verwendet werden, Frameless natuerlich auch.
Das Problem momentan ist, dass meine managed Beans (scope:session) nach einem normalen <a>-Link verschwinden - nehm an ich muss alles ueber die jsf-Navigation und den commandLinks regeln - dummerweise zerhauen mir die commandLinks das komplette Design. Ich hass layouten :x

Noch was zu der JSF:
bevorzugt ihr die *.faces oder faces/*.jsp ? Muss ich die Navigationsregeln auch immer dementsprechend anpassen? Hab Beispiele im Netz gesehn, bei denen das nicht der Fall ist!

Und noch mehr: h:dataTable
Gibt es vielleicht schon fertig eine 'vollausgestattete' Table, d.h. mit Sortierung wenn ich auf die Spaltenueberschriften klicke und vielleicht dynamischer Spaltenauswahl?

???:L :autsch: :bahnhof:

NAchtrag:
Meine Beans verschwinden immer :cry:
Code:
	<managed-bean>
		<managed-bean-name>userBean</managed-bean-name>
		<managed-bean-class>webui.bean.UserBean
		</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>
wieso?
wie kann man feststellen/loggen wann ne Session invalid wird?

Ablauf: nach dem Login (ueber userBean) lande ich auf "home" weils die jsf-Navigation so befiehlt. 1.Frage: wieso bleibt die Adresse (in der Browseradressleiste) gleich, d.h. immernoch /faces/login.jsp? Mein Header jedenfalls sagt dann noch dass ich eingeloggt bin. (= liesst einfach nur das userBean aus). Klick ich dann auf einen Link in "Home" lande ich auf der naechsten Seite, ganz brav nach der Navigationsregel -grosses Aber: ich bin nicht mehr "eingeloggt" (=userBean ist leer) UND die Adresse lautet nun /faces/home.jsp, also der Name der Vorgaengerseite!

Noch eine Frage: Browser-Back-Taste
drueck ich die Zuruecktaste, lande ich (bislang) beim Alten, nur ist der Erste Klick umsonst, d.h. es passiert erst mal nur ein Refresh wenn ich was machen moechte - also man muss 2x auf einen Link klicken damit es weiter geht? An was liegt das genau und kann man das beheben??

Bitte helft mir! Danke :###
 

Gumble

Bekanntes Mitglied
Gumble hat gesagt.:
1.Frage: wieso bleibt die Adresse (in der Browseradressleiste) gleich, d.h. immernoch /faces/login.jsp?
ok, hab was rausgefunden:
Code:
	<navigation-rule>
		<from-view-id>/login.jsp</from-view-id>
		<navigation-case>
			<from-outcome>home</from-outcome>
			<to-view-id>/home.jsp</to-view-id>
			<redirect />
		</navigation-case>
	</navigation-rule>
der redirect-Tag sorgt dass die Adressleiste upgedatet wird. Trotzdem hab ich noch soviele Probleme mit JSF. Hab das Gefuehl dass das ne grosse Scheisse ist.

Mach ich z.B. einfach mal ein Refresh (F5) nach dem 'Einloggen', kommt sowas undebuggables heraus:
16:35:12,140 ERROR [[jsp]] Servlet.service() for servlet jsp threw exception
javax.faces.FacesException: cannot add component with id '_id4' and path : {Component-Path : [Class: javax.faces.component.html.HtmlOutputText,Id: _id4]} to its parent component. This might be a problem due to duplicate ids.
at javax.faces.webapp.UIComponentTag.findComponent(UIComponentTag.java:401)
at javax.faces.webapp.UIComponentTag.doStartTag(UIComponentTag.java:219)
at org.apache.jsp.home_jsp._jspx_meth_h_outputText_8(org.apache.jsp.home_jsp:793)
at org.apache.jsp.home_jsp._jspx_meth_h_commandLink_2(org.apache.jsp.home_jsp:756)
at org.apache.jsp.home_jsp._jspx_meth_h_column_3(org.apache.jsp.home_jsp:677)
at org.apache.jsp.home_jsp._jspx_meth_h_dataTable_1(org.apache.jsp.home_jsp:629)
at org.apache.jsp.home_jsp._jspx_meth_f_view_0(org.apache.jsp.home_jsp:137)
at org.apache.jsp.home_jsp._jspService(org.apache.jsp.home_jsp:76)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
...
Caused by: org.apache.jasper.JasperException: cannot add component with id '_id4' and path : {Component-Path : [Class: j
avax.faces.component.html.HtmlOutputText,Id: _id4]} to its parent component. This might be a problem due to duplicate ids.
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:370)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
Dabei hat die Seite kaum Inhalt - nur ein (command)Link auf ne andere Seite.
 

tec1

Aktives Mitglied
Warum legst du soviel Wert darauf, dass die Adressleiste geupdatet wird? Wenn du nicht gerade Bookmarks mitten in der Anwendung erstellen wilst, ist doch die Adressleiste völlig uninteressant.

P.S. Schaue dir mal die ADF Komponenten von Oracle an, die sind jetzt open source(kommen ins myfaces Projekt) und ziemlich gut.
 

KSG9|sebastian

Top Contributor
html-elemente solltest du inn f:verbatim-tags verpacken:


Code:
.
.
<f:verbatim>
[url="http://www.google.de"]Link zu google[/url]
</f:verbatim>
 

Gumble

Bekanntes Mitglied
Danke fuer die Beitraege.
tec1 hat gesagt.:
Warum legst du soviel Wert darauf, dass die Adressleiste geupdatet wird? Wenn du nicht gerade Bookmarks mitten in der Anwendung erstellen wilst, ist doch die Adressleiste völlig uninteressant.

P.S. Schaue dir mal die ADF Komponenten von Oracle an, die sind jetzt open source(kommen ins myfaces Projekt) und ziemlich gut.
leg ich eigentlich auch nicht - nur wer weiss, was die Anwender mal mit meinem Programm anfangen? Gibt viele die bookmarken immer alles. Seltsamerweise sind die Adressen immer eine Seite zu spaet (wieso?). Gesichert ist leider auch noch nix, da ich JAAS & JSF nicht hingekriegt habe :(
ADF: hm, keine Ahnung. Auf noch mehr schlecht dokumentierte Frameworks hab ich ehrlich gesagt keine grosse Lust. Komm ich nicht auch ohne aus?

KSG9|sebastian hat gesagt.:
html-elemente solltest du inn f:verbatim-tags verpacken:

okay, aber wie ich vermutet habe, liegt das (eine) Problem nicht an den a-links sondern dass meine Sessionbeans generell verschwinden.

Wenn ich gerade mal schon mal dabei bin, dann noch ein paar Fragen:

wo gibts endlich mal gutes Material ueber JSF und dessen praktische Anwendung (die gut gemacht ist)?
hab mal das JSF-Buch von Andy Bosch von der Bib ausgeliehen und das war einfach nur schlecht. Manning und Horstmann wuerd ich gern mal lesen, aber diese hat die Unibib natuerlich nicht (<- daemliche Bib). Und kaufen? Bei der Kurzlebigkeit der heutigen Frameworks und fuer >40Eur? Ne.
Ich haet gern ein schickes Beispiel mit einem gesicherten JAAS-Login, bisschen Navigation und etwas DB-Zugriff. Und ohne EJB (nur sessionbeans). Ich nutze Hibernate fuer die Persistenz - und den Zugriff regel ich ueber eine SessionFactory Objekt das im JNDI zentral abgelegt wird. Die Instanz wird dann in den Context der Webapp gepackt. Ist das OK oder schlechtes Design?
Oder gibts noch - mehr frequentierte - JSF Foren? jsf-forum ist graesslich zu lesen, sun's jsf forum hat zuviele offene Fragen. Die kleinen (kostenlosen) Tuts à la laliluna kenn ich schon.... manman, wie habt ihr es geschafft 'rein' in die Materie zu kommen? Hab das Gefuehl ich renn gegen eine Mauer an :(

Mal wieder ein Nachtrag:
https://appfuse.dev.java.net
hat Beispielprojekte drin - die kann man sich sogar gleich online live angucken. Sieht sehr vielversprechend aus - gucke mir grad den Src von "JSF + Spring + Hibernate" in der 1.8.2er Version. Der Code ist sehr fein dokumentiert! Die Qualitaet kann ich nicht beurteilen, scheint aber auch gut zu sein. Kennt jemand von Euch die Seite?
 

Gumble

Bekanntes Mitglied
Layout-Problem:

header1.jsp
Code:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ page import="my.bean.*"%>

<html>
<head>
<link rel="stylesheet" type="text/css" href="css/my.css" />
</head>

<body>
<table border="0" cellpadding="0" cellspacing="0">
	<tr>		
		<td></td>
		<td width="100%" valign="top">
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
			<tr>
				<td><h:outputText styleClass="pageheader" value="You are logged in as " /> <h:outputText
					styleClass="pageheader" value="#{userBean.userName}" /></td>
				<td><h:form id="logoutId">
					<h:commandLink styleClass="pageheader"
						actionListener="#{userBean.logout}" action="logout" title="Logout">
						<h:outputText value="Logout" />
					</h:commandLink>
				</h:form></td>
			</tr>
...

wird aufgerufen:
Code:
<f:view>
	<jsp:include page="header1.jsp" />
...

Und er macht daraus:
Code:
	<span class="pageheader">You are logged in as </span><span class="pageheader">user1</span><form id="logoutId" name="logoutId" method="post" action="/webui/faces/login.jsp" enctype="application/x-www-form-urlencoded">
[url="#"]Logout[/url]
<input type="hidden" name="logoutId_SUBMIT" value="1"/><input type="hidden" name="logoutId:_link_hidden_"/><script type="text/javascript"><!--
function clear_logoutId() {
  var f = document.forms['logoutId'];
  f.elements['logoutId:_link_hidden_'].value='';
  f.target='';
}
clear_logoutId();
--></script></form>



<html>
<head>
<link rel="stylesheet" type="text/css" href="css/my.css" />
</head>

<body>
<table border="0" cellpadding="0" cellspacing="0">
	<tr>		
		<td></td>
		<td width="100%" valign="top">
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
			<tr>

				<td> </td>
				<td>
					
						
					
				</td>
			</tr>
...
Firefox1.5, JBoss AS4.0.3SP1, myfaces1.0.9, hier eingelogt als 'user1'
Für die Leserlichkeit hab ich ein paar Newlines eingefuegt - jsf schreibt naemlich den Anfang in eine Zeile (bis zum script).
Wunderlich ist jedenfalls, dass die beiden outputText-Tags aus der Tabelle herausgenommen werden und sogar noch vor dem html-Tag geschrieben werden. Firefox zeigts zwar, aber natuerlich nicht so wie ich es wollte. Hab in der Seite spaeter noch aehnliche Probleme, bei denen ebenfalls Dinge nicht in der table angezeigt werden, sondern vorher.
Wie kann ich mir das erklaeren, und vor allem, wie loesen??
???:L
 

Bleiglanz

Gesperrter Benutzer
du musst
Code:
<f:subview><jsp:include page="header1.jsp" /></f:subview>
schreiben damit das richtig funktioniert
 

Gumble

Bekanntes Mitglied
mag nicht:
Code:
<span class="pageheader">You are logged in as </span><span class="pageheader"></span><form id="header1:logoutId" name="header1:logoutId" method="post" action="/webui/faces/login.jsp" enctype="application/x-www-form-urlencoded">
[url="#"]Logout[/url]
<input type="hidden" name="header1:logoutId_SUBMIT" value="1"/>
<input type="hidden" name="header1:logoutId:_link_hidden_"/>
<script type="text/javascript"><!--
function clear_header1_3AlogoutId() {
  var f = document.forms['header1:logoutId'];
  f.elements['header1:logoutId:_link_hidden_'].value='';
  f.target='';
}
clear_header1_3AlogoutId();
--></script></form>



<html>
<head>
<link rel="stylesheet" type="text/css" href="css/my.css" />

</head>

<body>
<table border="0" cellpadding="0" cellspacing="0">
	<tr>		
		<td></td>
		<td width="100%" valign="top">
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
			<tr>
				<td> </td>

				<td>
					
						
					
				</td>
			</tr>
...
Vielleicht liegt es daran, dass die header.jsps 'unvollstaendig' sind, d.h. nicht jedes Tag hat unbedingt sein Counterpart. Nutzen tu ich das z.B. so: home.jsp
Code:
<f:view>
	<jsp:include page="header1.jsp" />Home<jsp:include page="header2.jsp" />

	[b]<h:messages />[/b]
...
und header2.jsp beginnt mit:

Code:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<f:subview id="header2">
</h2>
</td>
</tr>
</table>
</td>
</tr>
...

Hier noch ein Bild wie traurig das aussieht:
awful_layout.JPG

Es sollten das Userinfofeld und der Logout-Link in einer Zeile sein, die sich über den ganzen Bildschirm, in der Breite, erstreckt. Ebenfalls schief gelaufen sind die beiden Link 'Home' und 'Overview' - da besteht genau dasselbe Problem.
???:L
 

Bleiglanz

Gesperrter Benutzer
As you can see, the entire included page is enclosed in an <f:subview> tag, and all non-JSF tags and template text are enclosed in an <f:verbatim> tag. Alternatively, we could move the <f:subview> tag into the first page, around the <jsp:include> tag.
hmm

also in der header.jsp

alles in ein f:subview

und alles andere in f:verbatim

einschliessen?
 

Gumble

Bekanntes Mitglied
naja, alles kann man ja wohl nicht in ein verbatim-tag packen - dachte dass muss man eh nur fuer Ausgaben. table-Tags zum Layout wird man wohl so verwenden muessen, sonst ist der ganze jsf-Kram nicht zu gebrauchen. Aber selbst der Horstmann verschachtelt html mit jsf [Core JSF Beispielkapitel].
 

Gumble

Bekanntes Mitglied
Könnt die ganze Zeit fragen stellen, hab soviele Baustellen :(
Nochwas anderes, was ich zum Teil gerade loesen konnte:
seltsames reproduzierbares Verhalten: Tabelle wird auf 'home' gefuellt - Daten stammen aus einem Bean das im Request-Scope liegt. Drueck ich ueber mein unglaublich huebsche Navigationsmenue nochmal auf 'home' gibts Mist: erst Exception wegen ner id-Geschichte, nach Vergabe einer Id eines commandLinks innerhalb der dataTable, war die Exception weg, die Tabelle aber leer + doppelt (Bild2):
strange_table1.JPG

strange_table2.JPG

Das Verhalten konnte ich loesen in dem ich in der faces-config.xml noch eine Regel auf sich selbst (home.jsp ->'home' -> home.jsp) reingestellt habe. Ich vermute, dass das Request-Bean nicht wirklich neu erzeugt wurde. Nur beim Reload per Browser bleibt das Problem bestehen - was genau passiert eigentlich da? Wuerde gern das Problem verstehen und loesen - kann man die Erzeugung der Request-Beans 'erzwingen'?
 

Bleiglanz

Gesperrter Benutzer
na ja, wenn das Ding "Request" Scope hat

dann wird bei jedem Request ein neues erzeugt (weil ja auch der Request neu ist)

ist für JSF denkbar ungeeignet, weil du damit keine Daten über den Rountrip zum Browser hinwegretten kannst, du müsstest das manuell machen :)

also geh den Weg des geringsten Widerstands und mach session-scope draus, das ist zwar auch nicht unproblematisch aber für den anfang am einfachsten
 

Gumble

Bekanntes Mitglied
Bleiglanz hat gesagt.:
ist für JSF denkbar ungeeignet, weil du damit keine Daten über den Rountrip zum Browser hinwegretten kannst, du müsstest das manuell machen :)
Roundtrip zum Browser? ???:L
Den Teil hab ich mir gemopst und es funktioniert eben nur im Request-Scope. So einfach umbauen geht das nicht.
Noch ne allgemeine Designfrage. Den ganzen Datenbankenkram regelt ein Datenbankensessionobject, dass das Hibernatesessionobject wrapped. Erhalten tu ich das von einem Factory-Singleton das im JNDI global abgelegt wird. (holen tu ich es aber mit einer einfachen getInstance() Funktion, also ohne JNDI)
Wie regelt man nun das mit den session Objekten? Momentan liegt Eines in einem static ThreadLocal, dass in einem Filter zu Beginn jedes mal neu geoeffnet (+beginTransaction) wird, bzw am Ende commitTransactionAndClose bzw rollback. Also
Code:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {   
    boolean exceptionOccurred = true;
    log.info("do Filter");       
    PersistenceContext persistenceContext = Context.getPersistenceContext();
    try {     
      persistenceContext.beginTransaction();
      filterChain.doFilter(servletRequest, servletResponse);
      exceptionOccurred = false;      
    } finally {
    
      if (exceptionOccurred) {
        persistenceContext.setRollbackOnly();
      }
      persistenceContext.endTransaction();
    }
  }
In dem PersistenceContext steckt das besagte session-Objekt:
Code:
public class PersistenceContext {  
  static DataSessionFactory dataSessionFactory = DataSessionFactory.getInstance();
  boolean isRollbackOnly;
  DataSession dataSession;  
  public void beginTransaction() {
    isRollbackOnly = false;
    dataSession = dataSessionFactory.openDataSession();
    dataSession.beginTransaction();
  }
...
Nun greif ich in meinen Beans per "DataSession dataSession = Context.getPersistenceContext().getDataSession();" auf meine Daten zu. Was ist der 'Best Practice'? Lohnt es sich vielleicht den 'offiziellen' Context zu nutzen und nicht diesen Pseudocontext? Problem ist naemlich, dass bei der Umstellung, des einen Beans auf Session-Scope, es Fehler gibt: "the owning Session was closed". Auch ist mir aufgefallen, dass der Timeout nicht wirklich geht. Genauer hab ich das Verhalten noch nicht untersucht, aber ab und an ist die Hibernate-session geschlossen und der AS muss neu gestartet werden.
 

Bleiglanz

Gesperrter Benutzer
Was spricht dagegen, die HibernateSessionFactory in den application-scope zu legen und bei jedem Request eine neue Hibernate-Session zu öffnen (sag nicht Performance)

aber wenn schon jemand ein PersistenceContext geschrieben hat, dann wird man das wohl kaum los...dass du das Bean nicht auf session-scope legen kannst liegt wohl daran, dass es dann nicht mehr an die Hibernate-Session "gebunden" ist; diese wird ja für jeden Request neu erzeugt :)
 

Gumble

Bekanntes Mitglied
Bleiglanz hat gesagt.:
Was spricht dagegen, die HibernateSessionFactory in den application-scope zu legen und bei jedem Request eine neue Hibernate-Session zu öffnen (sag nicht Performance)

aber wenn schon jemand ein PersistenceContext geschrieben hat, dann wird man das wohl kaum los...dass du das Bean nicht auf session-scope legen kannst liegt wohl daran, dass es dann nicht mehr an die Hibernate-Session "gebunden" ist; diese wird ja für jeden Request neu erzeugt :)

Hmm, was ist die beste Methode um die Factory zu hinterlegen?
<Context/> im web.xml vs Application-scoped Bean im faces-config.xml vs static ThreadLocal im selbstgeschriebenen /Kontext?

Und wie sollte man die Session/Transaktionen benutzen?
Filter, d.h. bei jedem Request eine neue Session oeffnen und TRX starten. bzw am Ende TRX commit/rollback oder lieber direkt im Bean?

Irgendwas funktioniert bei mir naemlich noch nicht, und ich denke, dass da ein prinzipieller Fehler drinsteckt: laeuft der Server ueber nachts (tatenlos), so krieg ich nur ein Haufen seltsamer Fehler:

  • 17:07:51,931 ERROR [DataSession] org.hibernate.TransactionException: JDBC commit failed
    17:07:51,931 ERROR [[default]] Servlet.service() for servlet default threw exception
    java.lang.RuntimeException: couldn't commit transaction
    at my.data.hibernate.DataSession.commitTransaction(DataSession.java:59)
    at my.data.hibernate.DataSession.commitTransactionAndClose(DataSession.java:79)
    at my.webui.context.PersistenceContext.endTransaction(PersistenceContext.java:36)
    at my.webui.filter.PersistenceFilter.doFilter(PersistenceFilter.java:44)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    ....
    Caused by: java.sql.SQLException: No operations allowed after connection closed.Connection was implicitly closed due to
    underlying exception/error:


    ** BEGIN NESTED EXCEPTION **

    com.mysql.jdbc.CommunicationsException
    MESSAGE: Communications link failure due to underlying exception:

    ** BEGIN NESTED EXCEPTION **

    java.net.SocketException
    MESSAGE: Software caused connection abort: recv failed

    STACKTRACE:

    java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1902)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2351)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2862)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2988)
    at com.mysql.jdbc.Connection.commit(Connection.java:2161)
    at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115)
    ...
 

Bleiglanz

Gesperrter Benutzer
Filter, d.h. bei jedem Request eine neue Session oeffnen und TRX starten. bzw am Ende TRX commit/rollback oder lieber direkt im Bean?
ja, bei jedem Request neue Session und am Ende commit und close; am besten aus der Bean raushalten

zum Fehler: Hm, habt ihr einen Connection-Pool und ist evtl. das Timeout der Datenbank das Prob? Oder vergisst irgendwer seine Verbindungen zu schliessen? Bzw. zu commiten?
 

Gumble

Bekanntes Mitglied
Bleiglanz hat gesagt.:
ja, bei jedem Request neue Session und am Ende commit und close; am besten aus der Bean raushalten
oki, dann ist der Filter schon ne feine Sache.
Nochmal zum SessionFactory-Singleton - ich brauch das Ding doch gar nicht in irgendwelchen Scope legen, sondern es wuerde ja reichen, bei jedem Request mir die Instance zu holen. JNDI braeuchte ich ja auch nicht...
Bleiglanz hat gesagt.:
zum Fehler: Hm, habt ihr einen Connection-Pool und ist evtl. das Timeout der Datenbank das Prob? Oder vergisst irgendwer seine Verbindungen zu schliessen? Bzw. zu commiten?
Also die Datenbank ist ne lokale Standardinstallation, von pool und timeout hab ich keine Ahnung, aber offene Session, duerften ja nicht existieren, da ich mich am ausgeloggt (session invalidate) habe und sogar den Browsertab geschlossen habe. Tippe eher darauf, dass die (Hibernate)SessionFactory vielleicht "aus-timed" und neu initialisiert werden muss. Wenn ich naemlich den JBoss neustarte, geht wieder alles - der db-server muss nicht neugestartet werden.
 

Gumble

Bekanntes Mitglied
juhu, konnte das mysql/hibernate/session-timeout Problem loesen:
Code:
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.connection.autoReconnect">true</property>
<property name="hibernate.connection.autoReconnectForPools">true</property>
<property name="hibernate.connection.is-connection-validation-required">true</property>
hinzugefuegt in zur hibernate.cfg.xml
Was genau von den Zeilen wichtig ist, weiss ich allerdings nicht. Muss irgendwann mal nachschlagen, aber hauptsache es geht erstmal - glaub dieses validation verbraet relativ viel Performance, aber egal.
 

Gumble

Bekanntes Mitglied
Will das Thema Session-timeout mal ansprechen - hab naemlich heute den Versuch gemacht, in meiner Webapp angemeldet zu bleiben, um zu testen was passiert. Und zwar das:
  • 13:56:57,259 INFO [PersistenceFilter] do Filter
    13:56:59,852 ERROR [JDBCTransaction] JDBC begin failed
    com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

    ** BEGIN NESTED EXCEPTION **

    java.io.EOFException

    STACKTRACE:

    java.io.EOFException
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1905)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2351)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2862)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2988)
    at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:4913)
    at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:63)
    at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1309)
    at my.data.hibernate.DataSession.beginTransaction(DataSession.java:43)
    at my.webui.context.PersistenceContext.beginTransaction(PersistenceContext.java:25)
    at my.webui.filter.PersistenceFilter.doFilter(PersistenceFilter.java:29)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at my.webui.filter.ContextFilter.doFilter(ContextFilter.java:19)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
    at java.lang.Thread.run(Thread.java:595)


    ** END NESTED EXCEPTION **



    Last packet sent to the server was 1406 ms ago.
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2563)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2862)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2988)
    at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:4913)
    at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:63)
    at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1309)
    at my.data.hibernate.DataSession.beginTransaction(DataSession.java:43)
    at my.webui.context.PersistenceContext.beginTransaction(PersistenceContext.java:25)
    at my.webui.filter.PersistenceFilter.doFilter(PersistenceFilter.java:29)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at my.webui.filter.ContextFilter.doFilter(ContextFilter.java:19)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
    at java.lang.Thread.run(Thread.java:595)
    13:56:59,868 ERROR [DataSession] org.hibernate.TransactionException: JDBC begin failed:
    13:56:59,868 ERROR [[FacesServlet]] Servlet.service() for servlet FacesServlet threw exception
    java.lang.RuntimeException: can't rollback : no transaction started
    at my.data.hibernate.DataSession.rollbackTransaction(DataSession.java:67)
    at my.data.hibernate.DataSession.rollbackTransactionAndClose(DataSession.java:85)
    at my.webui.context.PersistenceContext.endTransaction(PersistenceContext.java:32)
    at my.webui.filter.PersistenceFilter.doFilter(PersistenceFilter.java:44)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at my.webui.filter.ContextFilter.doFilter(ContextFilter.java:19)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
    at java.lang.Thread.run(Thread.java:595)

Was passiert genau wenn die Session austimed? Einfach nur ein Flag gesetzt? Wie designed man diese Fehlerbehandlung nun am besten? Will ungern in den Beans danach pruefen - vielleicht durch ein <error-page> Tag in der web.xml? Gibts vielleicht da auch was JSF spezifisches?
 

KSG9|sebastian

Top Contributor
Mit connections schließen u.s.w. musst du n bissl aufpassen..vor allem wenn du die objekte lazy aus der DB holst..dann sind sie nämlich an das Session-Objekt gebunden und werfen eklige Exceptions beim Session-close.
 

Gumble

Bekanntes Mitglied
Komplizierte Sache das ganze :(
Wie testet man nun die TimeOut-Problematik am besten? D.h. an welchen Stellen ueberall (-> xml) muss man den Timeout runtersetzen? (http-session?, hibernate-session?, jdbc-session? ... evtl. jta, jsf ..??)
Und wie krieg ich am elegantesten eine Fehlerpage? So ein Stacktrace mag vielleicht fuer uns Entwickler prickelt sein, aber die (dummen) User sehen das anders :wink:
Das geht jedenfalls nicht:
Code:
<error-page>
		<exception-class>java.lang.Exception</exception-class>
		<location>/faces/error.jsp</location>
	</error-page>
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben