Java VIII
Syntax extensions
The new "intrude" statement provides convenient access to an object's private members. Here is a usage example:
Object x;Outside the block, the variable x can be used just as if it had been assigned from a regular public method. This results in much shorter code than the old technique of using "java.lang.reflect" to accomplish the same thing. To circumvent possible abuses of this new feature, it is recommended that any sensitive private data is stored as RFC4648-encoded text strings wrapped in XML documents that encrypt the data according to the W3C XMLENC-CORE standard.
intrude (foo) {
x = foo.privateMethod();
}
New annotations
In response to the increasing demands for higher programmer productivity, a new annotation is provided that makes it easier to get away with quick-and-dirty code:
@ShamelessWhen this annotation is used, the -Xlint option to javac will be completely disabled during compilation of the annotated code block. Also, some "slack" will be allowed for indexing outside array bounds. Exactly how much slack there will be has not yet been finalized, but the intent is that the programmer should never have to worry about trivial fence-post errors.
public void foobar() {
...
}
Memory management
New state-of-the-art memory management. For environmental reasons, garbage data will in the future be viewed as a valuable local resource rather than "waste" that has to be managed and removed by a centralized service. Traditional garbage collection has been deprecated in Java VIII and in its place there is an assertion-based API contract that forces all consumers of heap objects to recycle used objects back to their producers. This is technically done via a new signature for the "java.lang.Object.notifyAll" method.
All this is very exciting, and I am looking forward to the planned alpha release of Java VIII which is preliminary scheduled for April 1, MMXI.
Embedded Derby on a socket, revisited
In an earlier post in this blog I described how to turn on a listening socket for the embedded Derby that is bundled with GlassFish. That method configures the embedded Derby to behave like the standalone Derby: the listening socket is on port 1527 and Derby's system directory is "/opt/glassfish/databases", just like in the standalone server.
But I have realized that this is not a good thing, for several reasons. One is that applications that use the embedded Derby client will find their databases in a non-standard location. The standard system directory for embedded clients is "/opt/glassfish/domains/domain1/config". This is problematic for applications such as Jackrabbit that create their own files in that directory and expect Derby to use the same directory structure. Another reason why it's bad is that there are initialization issues for applications that use the Derby network client. The network listener is opened when the first embedded database is booted, but this still doesn't make the JDBC resources available early enough in all cases.
So enabling a built-in network listener is no substitute for running a standalone Derby server. However, it is still useful for debugging and maintenance, by allowing you to connect with a client such as ij or SQuirreL. My GlassFish configuration now contains the following extra properties:
<jvm-options>-Dderby.drda.startNetworkServer=true</jvm-options>This starts the network listener but keeps the Derby system directory in the standard place for embedded clients. And it uses port 1528, leaving the standard port 1527 free for use by the standalone Derby. Just put the above lines among the
<jvm-options>-Dderby.drda.portNumber=1528</jvm-options>
<jvm-options> in the file "domains/domain1/config/domain.xml" (after shutting down GlassFish first of course).
JSF and RESTful URLs
Consider the following scenario. You have a widget administration application that contains three pages:
list.jsp, details.jsp, and create.jsp. The page list.jsp presents a list of links of the form details.jsp?id=4711, where 4711 is the key for a particular widget. This is easy to accomplish with the JSF tags <h:dataTable> and <h:outputLink> with a nested <f:param> for the id parameter. Now for the difficult part. We have a form in create.jsp for creating new widgets. When the form is submitted, our backing bean creates a new widget, producing a new id value. Let's say the new id value is 4712. We want the response page to be details.jsp?id=4712. Unfortunately this is not possible, due to the rigid XML-driven navigation system in JSF.Apart from modifying or extending JSF to fix this, I can see two possible workarounds: the first is to short-circuit JSF navigation completely by letting the response page do
<jsp:forward> to another servlet which sends a redirect to the final URL. I haven't tried this. The second workaround is a compromise: let details.jsp without the id parameter show the last widget that was created in the current session. This has potential race condition issues if two windows in the same browser session create widgets concurrently, but this is probably a negligible problem.I used the following approach for the second method. Two backing beans,
SessionBean and RequestBean. The only purpose of SessionBean is to keep track of the last created id. RequestBean has two <managed-property> declarations: one for the id, with <value>#{param.id}</value>, and one for the session bean, with <value>#{SessionBean}</value>. The RequestBean's id property is normally set by the HTTP GET query parameter, but when invoked without this parameter the bean defaults it from SessionBean instead. This is done in an initialization method that also picks up the widget data from the database:@PostConstructSince the
private void init() {
if (id == 0) {
id = sessionBean.getId();
}
widget = entityManager.find(Widget.class, id);
}
RequestBean is initialized from the SessionBean in this situation, the POST-Redirect-GET pattern can be used for the response with no extra effort. Just put a <redirect/> in the <navigation-case> in faces-config.xml.The above solution is not 100% ideal, but it's good enough to satisfy the basic demands of RESTfulness since each URL represents a fairly well-defined resource.
