Archiv | Softwareentwicklung RSS für diesen Abschnitt

JSF: Multiple ‚javax.faces.ViewState‘ hidden fields

If you happen to have more than one h:form in your JavaServer Faces page, JSF will generate a hidden input field with javax.faces.ViewState as its name and id for each form. This breaks XHTML compatability because you have more than one element with the same id which isn’t allowed. I recently came across this myself and had some trouble finding a solution on Google. The problem results from an error in the JSF specification itself and thus cannot be solved easily but both major implementations have builtin workarounds:

For MyFaces, you can specify a context parameter in your web.xml called org.apache.myfaces.RENDER_VIEWSTATE_ID and set it to false. It will prevent MyFaces from rendering duplicate ids. For more information please refer to the MyFaces Bugtracking system (MYFACES-1700).

If you use the reference implementation (currently Mojarra), the name of the context parameter for the web.xml is com.sun.faces.enableViewStateIdRendering and you must also set it to false to prevent the RI from generating duplicate ids. For more information, please refer to the JSF-RI FAQ or the bugtracking system (issue 443).

How to get rid of „Could not resolve a persistence unit corresponding to the persistence-context-ref-name …“ exceptions

One error that’s been bugging me since I started out using Spring together with JPA in a Glassfish Application Server was an exception such as the following:

com.sun.enterprise.deployment.backend.IASDeploymentException: Could not resolve a persistence unit corresponding to the persistence-context-ref-name [de.icanmakeit.jpokerstats.jpa.dao.GameDao/_entityManager] in the scope of the module called [jpokerstats]. Please verify your application.

The core problem here is that the mentioned GameDao uses the @PersistenceContext annotation to obtain an EntityManager from the container (or in this case Spring) but there are multiple persistence units defined in the persistence.xml (for the live system, for testing, etc.) and the Glassfish is unable to decide to which of these persistence units the annotation should be mapped.

Since I wanted all of this to be managed by Spring, I didn’t bother this error and worked around it by downgrading the web.xml from 2.5 to 2.4 which disabled the J5EE dependency injection mechanism in Glassfish and let Spring do its job. Simply specifying @PersistenceContext(unitName=“myunit“) wasn’t an option, since the same classes use a different persistence unit during JUnit tests and on the live server and explicitly specifying a persistence unit name breaks the unit tests.

Since my „inner ITIL“ requires a developing solution after finding a workaround, I searched around the net, read a couple of dozen forum posts and finally figured out a way to solve the problem (…which I could have done earlier if I only had read the complete J5EE specification… *yawn*).

When deploying a 2.5 web application to Glassfish, the server examines it for any dependency injection annotations such as @PersistenceContext. It generates a default name for any unnamed annotation by using the FQCN, appended with a slash and the name of the field/property that is the injection target. In the above example, this would result in the name de.icanmakeit.jpokerstats.jpa.dao.GameDao/_entityManager. The server then tries find a persistence unit reference for this name. If there is only one persistence unit defined, this one will be used, otherwise the deployment descriptors are checked for configuration hints.

So in order to solve this problem, we have to provided these configuration hints. Adding the following few lines to the web.xml solves the problem:

This approach has one major drawback: if your software contains more than one @PersistenceContext injection target, you have to define a persistence-context-ref for each occurrence. This situation can be avoided by naming each @PersistenceContext annotation and giving them all the same name (note: the correct attribute is name, not unitName):

All injection target with the same annotation name can now share a single persistence-context-ref (you can also use this name to look up the persistence unit using JNDI):

Update: Below you’ll find the relevant parts of the Spring configuration file for the example above. It defines two beans, the first one makes the datasource, that has been configured in the Glassfish Server, available for use in Spring. The second one defines the entity manager factory that Spring will use to support the JPA context.

Developing lightweight Java web applications – Part 5: Templating with Facelets

Update 2012-05-28: I have deleted the project over at Google Code since I never finished it and it is outdated by now. Please refer to other, more state-of-the-art tutorials regarding building web applications with Java. In addition, comments are also closed on these posts.

Turning the app into a webapp

After creating a small persistence layer for our JPokerStats application, it is now time to finally create a web application out of our sources. If you already have the source files from the previous parts, you may have noticed the src/main/webapp directory that was created by the Maven archetype plugin. Let’s start here.

Getting the sources

As always, you can either go the project website or checkout the associated tag from the source control system:

svn checkout http://jpokerstats.googlecode.com/svn/tags/tutorial_part_05

Integrating Faces and Facelets

A web.xml is already present, and for a JSF application we will need to declare the JSF servlet here. We will also add some additional configuration options for debugging purposes and will map all requests to the /faces/ context to the servlet. This results in the following basic web.xml:

Weiterlesen…

OpenSource und das inhärente Problem

OpenSource ist eine tolle Sache und ich stehe voll dahinter. Als Java-Entwickler ärgere ich mich immer, wenn ich Bibliotheken benutzen muss, bei denen ich mir nicht ansehen kann, wie sie funktionieren. Denn wenn sie mal nicht funktionieren, bleibt nur noch der Support des Herstellers, obwohl das Problem vielleicht trivial ist.
Viele behaupten immer noch, OpenSource hätte zahlreiche Probleme wie z.B. Sicherheit und Qualität. Aus Erfahrung kann ich sagen, wenn die Community groß genug ist (wie bei vielen bekannten Projekten) dann gibt es weder ein Sicherheitsproblem noch ein Qualitätsproblem. Lediglich Fehler, die auch in closed source Software zu Problemen führen kann, z.B. mangelnde Absprache (siehe Debian/OpenSSL-Debakel).
OpenSource hat aber ein anderes, inhärentes Problem, und das ist die mangelnde Duldung durch Unternehmen, die mit Software an sich und obskuren Patenten ihr Geld verdienen. Das konnte ich heute wieder sehen, als ich eine Mail von SourceForge mit den Stimmkategorien für die OpenSource Awesomeness Wahl bekam. Dort gibt es u.a. die Kategorien:

  • Most Likely to Be Ambiguously Accused of Patent Violation
  • Most Likely to Get Users Sued

Andererseits spiegeln die Kriterien auch das Selbstverständnis und den Idealismus von OpenSource wider:

  • Most Likely to Change the World

JAX-WS and soap:address

JAX-WS is the easy-to-use Java API for XML-based web services and provides developers with an easy way to implement SOAP-based or ReSTful web services without having to fiddle with SOAP, WSDL or any XML at all (apart from the configuration).

If you use the „from-Java“ approach to JAX-WS, the runtime will automatically generate a WSDL file for your service that will be available under an URL such as http://localhost:8080/my-service/myAction?wsdl. It contains a part such as

to point the clients that later will use this service to the correct URL to address the service itself. Very soon I came across the question, how to deploy this to a production environment, where the service and the client would, of course, run on different machines. The above excerpt from the WSDL isn’t really portable from the way it look.

As a beginner with JAX-WS, at first I found no way to change this URL to reflect another server as localhost and got frustrated with the question how on earth to deploy this web service and change the soap:address part. As it turns out now, you don’t have to change this part.

The service address (as the whole WSDL file) is generated on-the-fly by JAX-WS when a client requests it. The runtime then simply derives the service’s address from the request URL for the WSDL file. So, if you can request it from http://localhost:8080/my-service/myAction?wsdl, the service address will read as shown above. If you deploy this to another server and address it for example with http://prod-ws.mycompany.tld/my-service/myAction?wsdl then the runtime will generate the following address:

and everything will be fine. I hope, I could save you some headache with this.