Releasing 1.0 of Application foundation

I’m happy to announce the first release of the Application foundation project!

The project’s goal is to provide a simple and lightweight foundation for Vaadin application. The project consists of individual modules which are designed to be used separately or in combination with other modules. Minimization of dependencies to other modules and third party libraries have been one of the primary goals with the module designs.

With the application foundation library you get commonly used features to your application with minimal work. I’ve created an example application called Flea market, a place where registered users can place advertisements about items they want to sell. The entire application was written in less than five hours from scratch to deployment. The application includes registration of new users, authentication, database storage and the application is translated into three different languages (the language used depends on the default locale). Check out the demo application at
http://kim.virtuallypreinstalled.com/Fleamarket

The first release of the application foundation contains four modules


Persistence

Most applications, even though how simple, often need some kind of persistence of data. The persistence module’s purpose is to provide a simple JPA-based persistence for Vaadin applications, without the developer having to worry to much about such terms EntityManagers? or session management.

Dependencies

  • EclipseLink


Authentication

The authentication module provides a simple implementation for authenticating users in a Vaadin application. The module does not only provide authentication, but also the session management of logged in users. It also provides a set of helpful utility classes for commonly executed operations.

Dependencies

  • The persistence module


Internationalization

Often applications need to be written for a multilingual audience. Therefore we must have a way to easily make translations of our applications. Even though you know that your application will not need any translation, it is still a good practice to keep the natural language strings away from your application code. The internationalization (i18n) module will help you accomplish that task.

Dependencies

  • XOM XML parser


View handling

When your application grows, the complexity of your user interface code grows as well. At some point, you might want to create cross-references between different UI components. If your user interface hasn’t been designed for such operations, building the required logic afterward can be a tedious task. The view module provides a simple way to activate and cross-reference different parts of the application’s user interface.

Dependencies

  • None

Relevant links:

Awesome! I think this kind of thing is exactly what guys like me, who don’t like playing around with the backend stuff more than necessary, need to get applications flying quickly.

This could be a good companion for my new
theme editor
, I could persist different styles per user and allow them to edit and download them later on. What do you think, would this framework be a good fit for it?

I think it would be a perfect fit :slight_smile:

Great stuff, surely useful for many!

Sounds promising.

One bug report. When I try to modify any of the messages in the demo and press save, I’ll get the following:


Exception
com.vaadin.event.ListenerMethod$MethodException
Cause: javax.persistence.RollbackException: Exception [EclipseLink-4002]
 (Eclipse Persistence Services - 2.0.0.v20090423-r4028): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Violation of unique constraint SYS_PK_49: duplicate value(s) for column(s) ID in statement [INSERT INTO appuser (ID, CONSISTENCYVERSION, USERNAME, EMAIL, NAME, PASSWORD) VALUES (?, ?, ?, ?, ?, ?)]

Error Code: -104
Call: INSERT INTO appuser (ID, CONSISTENCYVERSION, USERNAME, EMAIL, NAME, PASSWORD) VALUES (?, ?, ?, ?, ?, ?)
	bind => [2, 1, demo2, null, null, c824c5cfe374bc3db44ef84e39961bdef2235b88]

Query: WriteObjectQuery(org.vaadin.appfoundation.authentication.data.User@1a54b82)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:507)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
	at com.vaadin.ui.AbstractComponent.fireEvent(AbstractComponent.java:1107)
	at com.vaadin.ui.Button.fireClick(Button.java:341)
	at com.vaadin.ui.Button.changeVariables(Button.java:177)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1060)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:561)
	at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:260)
	at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:438)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
	at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283)
	at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:767)
	at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:697)
	at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:889)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
	at java.lang.Thread.run(Thread.java:619)
Caused by: javax.persistence.RollbackException: Exception [EclipseLink-4002]
 (Eclipse Persistence Services - 2.0.0.v20090423-r4028): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Violation of unique constraint SYS_PK_49: duplicate value(s) for column(s) ID in statement [INSERT INTO appuser (ID, CONSISTENCYVERSION, USERNAME, EMAIL, NAME, PASSWORD) VALUES (?, ?, ?, ?, ?, ?)]

Error Code: -104
Call: INSERT INTO appuser (ID, CONSISTENCYVERSION, USERNAME, EMAIL, NAME, PASSWORD) VALUES (?, ?, ?, ?, ?, ?)
	bind => [2, 1, demo2, null, null, c824c5cfe374bc3db44ef84e39961bdef2235b88]

Query: WriteObjectQuery(org.vaadin.appfoundation.authentication.data.User@1a54b82)
	at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
	at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
	at org.vaadin.appfoundation.persistence.facade.JPAFacade.store(JPAFacade.java:185)
	at org.vaadin.appfoundation.example.ui.AdModificationView.buttonClick(AdModificationView.java:87)
	at sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:487)
	... 24 more
Caused by: Exception [EclipseLink-4002]
 (Eclipse Persistence Services - 2.0.0.v20090423-r4028): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Violation of unique constr

Thanks, it was a small bug that had slipped into the example application (that’s what you get for coding so quickly ;)) but now it should be fixed. Also fixed another bug in the example application related to optimistic locking.

I’ve released the 1.0.2 version. It includes mainly bug fixes to the i18n module. If you are using the i18n module, make sure you read through the updated
documentation
. The usage of the new Lang class will now be required when using the i18n module.

Do the views you support allow me to open views in separate browser windows so that users can have multiple browsers open on the same application login session?

Is there any plan to allow views to be opened either by replacing views or by opening the views in separate windows (in this case, Vaadin windows within the same browser window)?

How about having views open into tabs so that they stay open/loaded until the tab is closed? And if the user selects the same menu item / navigation item, it could either re-open the tab if one already exists or even a new tab (though I’ve personally found the latter to be confusing and end up with lots of tabs when I’m browsing through features).

How about views that check before they are closed (same for separate windows if they are supported) to avoid data loss in forms and such?

How about support for UriFragmentUtility?

Just trying to get a feel for how much it allows out of the box. Thanks!

This is not possible with Vaadin, because each browser window would share the same application session. A change in one browser window would invalidate the state of the application in another browser window.

It’s up to the developer to decide how views are opened/replaced. All you need to do, is to implement the ViewContainer interface. In other words, there’s nothing that would stop you from implementing the ViewContainer interface directly in your application class and then have your application open the views in Vaadin windows.

Are you talking about browser tabs (in which case the answer is the same as in the first question) or tabsheet tabs (in which case the answer is the same as in the previous question)?

Actually, currently there is no event sent to a view when the view is being close, but you’ve got a valid point. I will include this feature in future versions.

Good idea, this could be a nice feature to have. I surely can see cases where it would be really useful.

Thank you for taking the time to get acquaintance with the library. This is library is quite new, so all feedback is worth gold to me.

Live and learn. Apparently you can have several Vaadin windows open in one application session and have each window open in a separate browser tab/window (you need to override the application getWindow method to make it work (if I remember correctly)). Anyway, this library’s AbstractView is just a normal CustomComponent with its own API. So once again, it’s up to the developer to implement the ViewContainer and handle the activations of the views in any way the developer wants to.

How about integrating/copying from Navigator -component to AppFoundation project? It handles all the stuff related to bookmarking, views and multiple windows.

I second Joonas suggestion, adding support for bookmarking, views and multiple windows would be great!

I’m new to Vaadin, and I just gave the application foundation a try, and found AppFoundation to be very helpful.

When I switched the DB over from HSQLDB to MySQL, I found a bug in the example program. The default JPA column length is 255, and some of the example messages inserted are longer than that.

The fix is just to add an annotation, to make the “message” column larger in Advertisement.java.

For example:
@Column(length = 4096)
private String message;

Another thing, that I think could be improved would be to add a few quick explanations on how to get the example up and running after doing the quick install. I think it would save people some time when they first are starting out.

I’ve evaluated the Navigator component and decided that I do not want to copy it as such to the AppFoundation project. The Navigator handles adding and replacing of the views in its internal layout, this is not what the view module is even designed to do. The view module’s purpose is to provide a static way to activate any view in the application from any place in the application, in other words, the ViewHandler only delegates the action to the proper classes with the given parameters. It was never even designed to handle the actual removing/adding of layouts in the application and this is the way I intend to keep it.

That being said, the upcoming 1.0.3 release will include support for defining uris for views thus enabling bookmarking. Thanks to these new changes, it should be trivial to make an implementation of the Navigator component which uses the view module. This is something I might include in upcoming versions.

I’ve commented Joonas’s suggestion in the previous reply. I’ve uploaded a new
prerelease version
of the upcoming 1.0.3 version. This prerelease includes defining uris for views.

Note that the prerelease version has a changed API in some modules (compared to 1.0.2) that is still undocumented. The actual release of 1.0.3 will be out once I’ve had time to finish all unit tests and update the documentation.

I’m very pleased to hear this! All feedback is more than welcome, may it be criticism or suggestion for improvements.

Good catch, haven’t tested example application with any other database than HSQLDB, I was in a bit of a hurry to get it published :slight_smile: I’ll make sure to fix this error when I’m upgrading to the newest release of app foundation.

Yup, probably some quick guides to each module would also be in order.

Thank you for the feedback!

I’m pleased to announce the release of version 1.1 (
download
)

The newest release includes improvements to existing features and some new features have been added. To summarize the biggest changes:

  • i18n module now supports multiple translation files
  • Views support activation by URI fragments
  • ViewFactories can be used to instantiate view objects in a custom way
  • The entire framework is now unit tested, with a code coverage of 92.1%

See the
release notes
for more information.)

I checked the project today regarding persistency and i18n modules and here are …

== Initial thoughts ==

Very good, clean and what’s best of it, simple API. I suggest people try this out. Note, I only checked persistency and i18n modules.

== Storing POJOs is way too cumbersome ==

Just look at the code what it does. After each store we fetch stored POJOs from entity manager and copy each field recursively from stored entity into original POJO, also if field contains another POJO then same trick is done for that too recursively. In JPA world it’s a neccessity that cannot be avoided if people are using cascade rules. This means that you can modify multiple pojos Y that are referenced by pojo X and then you can store changes simply by stating store(X) which in fact is not actually changed. Cascade takes care of storing referenced POJOs recursively. In my opinion, this is just dumb and it kills already questionable performance that complex JPA implementations have. I dislike this a lot, respectfully :smiley:

As a workaround you could stop using cascade and start designing your code more explicitly regarding what you store, should not be that hard. Remove recursive refresh call from facade’s store methods and replace them with code that copies AbstractPojo.id and AbstractPojo.consistencyVersion from stored pojo. Kim could take a notion of this in readme or even offer this through Facade API somehow?

Better yet you might consider using JPA for most persistency stuff and throwing in nosql solution for those parts that really require lightweight solution. Sometimes a mix of beatiful JPA implementation and crude nosql implementation is the best solution.

== Id generation for the POJOs ==

Sometimes you need an id for any pojo before you store it through entity manager. There exists articles that suggest generating ids with bulky java.util.UUID but I’d like to remind that simple long counter for id’s suffices fine. Create own sequence creator in pure Java which generates ids incrementing field sequence which is of type long. You can easily make it work in multi JVM’s or multi databases too if required. Every JVM has a sequence generator which periodically reserves new batch of id range from the database. Now your AbstractPojo equals and hashcode methods are extremely light when compared to using UUIDs. Another bonus is that id generation is not dependant to database implementation. For example, on MS SQL sequences are table specific and not unique per different AbstractPojo classes, but on PostgreSQL AbstractPojo id sequence is unique.

== You state that there’s no transaction control for the developer ==

Taken from Wiki: “Note that you will not have control of transactions yourself, but if you need to store several entities in one transaction, then you can use the storeAll-mehtod. Transaction control is not allowed due to the shared facade.”

This is perhaps the first thing you should consider to enhance in your project. Of course transactions are possible e.g. by extending Facade, it’s easy but perhaps you find even better ways to accomplish this?

Kim, great start!!

Another comment regarding i18n, it’s great otherwise but I’m still unsure if using SystemMsg is a good move or not. Javadoc states that refactoring lang id’s is easier but how common requirement this would be? And still, if you refactor SystemMsg’s, your translation.xml is broken unless you open it with text editor and fix id’s from there too. To me, using SystemMsg is a bit of extra nuisance when adding new translations and I fail to see benefits of it. Currently you have to 1. edit java code, 2. edit SystemMsg and 3. edit translations.xml to add an translated message. Having compile time checked id’s through SystemMsg does not provide you 100% safety, you can still typo id on translations.xml and code woudl compile fine…

Could it be better (=simpler) to use simply without SystemMsg class like this:


Lang.get("INVALID_CREDENTIALS");

This is quite small thing but might make life easier for developers on the long run…

The actual i18n module doesn’t use the described enum, only the example application does. The actual i18n module in the Application Foundation doesn’t care how you define the tuids, you can use enums or whatever format you like…

Lang.getMessage() does exactly that. You are not forced to use the enum in any way, as said, it only exists in the example application. So Application Foundation itself already works the way you’d like it to work :stuck_out_tongue:

Note that the i18n module contains a FillXml tool for maintaining your translation file(s). See documentation for more details.

And for any new people reading this thread, the application foundation can also be downloaded via
the Directory
.

Hi,

I wanted to switch the DB HSQLDB to MySQL, but I get the error page…


HTTP Status 404 -

type Status report
message
description The requested resource () is not available.

Apache Tomcat/6.0.20


Below is the setup:

_________________________________________________________________________

What else i need to do, please advice

thanks
zie

Do you have the mysql driver in your WEB-INF/lib folder? If not, it can be downloaded at
http://dev.mysql.com/downloads/connector/j/