Blog do projektu Open Source JavaHotel

sobota, 19 maja 2012

JSPWiki in the Cloud, JAAS security

I spent some time enabling JAAS security implemented in JSPWiki. After removing some bugs in the JSPWiki I was successful in the development mode (with options like: "Log in", "Preferences", "Adding new user", "Adding group" etc.). But after deploying to Google App Engine it failed with message like:
2012-05-18 23:41:43.072
org.apache.log4j.Logger error: Failed to start managers.
java.security.AccessControlException: access denied (javax.security.auth.AuthPermission modifyPrincipals)
 at java.security.AccessControlContext.checkPermission(AccessControlContext.java:355)
 at java.security.AccessController.checkPermission(AccessController.java:567)
 at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
 at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
 at javax.security.auth.Subject$SecureSet.add(Subject.java:1076)
 at java.util.Collections$SynchronizedCollection.add(Collections.java:1634)
 at org.apache.wiki.WikiSession.invalidate(WikiSession.java:615)
 at org.apache.wiki.WikiSession.guestSession(WikiSession.java:775)
 at org.apache.wiki.WikiSession.staticGuestSession(WikiSession.java:805)
 at org.apache.wiki.WikiSession.getWikiSession(WikiSession.java:744)


I also realized the in the development mode I added the following parameter to "Run" configuration : -D--enable_all_permissions=true just turning the security off. But of course it is out of my control in the production mode.
It seems that although javax.security.auth is listed on the Google App Engine list of supported packages it does not work and there is no way to overcome it.
So after spending some time I'm again at the very beginning with JSPWiki security. I see two options available : create security mechanism on my own or reuse some existing security framework (like Spring security).

niedziela, 6 maja 2012

JSPWiki in the Cloud

I started a cleaning phase and deployed a new version of JSPWikiForClouds.  So far I remove all references to javax.management. This package is not supported by Google App Engine and cannot figure out how to overcome. It does not seem impact core functionality. Solution implemented by javax.management (for instance: user management) should be resolved completely differently.
Current development status is available here.
Next step
Next step is to remove oscache package. This package is deprecated and not supported any longer. I will have to understand what is the role of this package in the JSPWiki application and decide if it can be simply removed or replaced with JCache (Google App Engine supports JCache to some extends).

wtorek, 1 maja 2012

JSPWiki in the Cloud

Story
I have been a user of the JSPWiki for years. I have it installed on my computer and simply using it as a local place for keeping different information and links. But for some time I have been wondering about putting it in the cloud (Google App Engine) and have it available from every computer I'm using, not only from my desktop. The only problem seemed to be that current PageProvider implementation (the way how wiki pages are persisted) does not support Google App Engine data store. But plugin based design of JSPWiki seemed to make it simple - just next implementation of PageProvider interface. So I started working moving JSPWiki into to the world (heaven) of clouds.
But I realized soon that Google App Engine implementation of PageProvider is the simplest piece of work.  The current implementation of JSPWiki cannot be executed in Google App Engine and substantial changes are necessary. What more important,  after having it running in development mode a lot of problems came up after deploying to a production environment. Also keeping backward compatibility with existing implementation JSPWiki is not possible. For instance : threads are not supported in Google App Engine but thread based services are not implemented as plugins but embedded inside the code.
The list of problems I found and solutions implemented is available here.
But finally, after fighting, loosing and winning a lot of battles, the first version emerged. It is only a subset of all features available but the core functionality is working. It also proves that the task (Google App Engine migration) is doable at all - this question was hovering over me all the time. So the PoC is passed.
Full source code is available here - I opened a new Open Source project.
What next
The purpose is of course to enable all features available but I cannot tell now when this target will be hit. The very first stage is cleaning. After breaking backward compatibility with the main JSPWiki trunk just remove all stuff  not used and temporary fixes.
After having the code clean the first feature implemented is security. Implementing authentication and authorization using services supported by Google App Engine. Probably the best method of authentication is Google authentication.


wtorek, 17 kwietnia 2012

Byliśmy na koncercie

W dniu 6 kwietnia 2012 byliśmy na finałowym koncercie XVI Wielkanocnego Koncertu Beethovenowskiego, muzyka się nam podobała, ale reżyseria koncertu mniej.
Męczeństwo Świętego Sebastiana Claude'a Debussego  to rzadko wykonywana muzyka tego kompozytora, według zapewnień organizatorów było to pierwsze wykonanie w Polsce. Pierwotnie była skomponowana jako ilustracja muzyczna do sztuki Gabriele d'Annunzia. Sama sztuka jednak nie zdobyła sobie powodzenia i została natychmiast zapomniana. Natomiast muzyka na szczęście nie podzieliła losu sztuki. Oczywiście nie ma możliwości odtwarzania muzyki tak jak to zamierzał kompozytor, najczęściej jest wykonywania jako czteroczęściowa suita.
Ale co się nam nie podobało ? Było złym pomysłem wprowadzenie narracji przed rozpoczęciem każdego aktu, nawet jeśli wygłaszającym tekst był znakomity aktor Andrzej Seweryn. To nie są porywające czy niezwykłe teksty, można było je opuścić bez żadnego zubożenia koncertu.  Natomiast rozbijało to ciągłość i utrudniało odbiór muzyki. A wielka szkoda, bo muzyka jest bardzo efektowna, właśnie za to tak lubimy Debussiego. Bardzo zmienna, dynamiczna, bogato zinstrumentalizowana, z dużą rolą instrumentów dętych. Dodatkowo w bardzo dobrym wykonawstwie Sinfonii Varsovii, Chóru Filharmonii Narodowej, solistek (chociaż tutaj miały mniejsze pole do popisu), zaś całością bardzo dobrze dyrygował Sylvain Cambreling.
Na pewno bardzo dobrym pomysłem organizatorów było sięgnięcie po mniej znany, ale także znakomity repertuar. Ale wielka szkoda, że efekt został trochę zniweczony przez nieprzemyślaną koncepcją realizatorską.


poniedziałek, 16 kwietnia 2012

Google App Engine and getLocalizedMessage

Problem
I found a nasty problem in Google App Engine - look at this JSP code.
Sometimes it is very useful to get localized message in JSP scriplet. For instance,  to use it as a parameter to other java method or as a attribute value to a JSP tag.
<%
  String hello = LocaleSupport.getLocalizedMessage(pageContext, "Hello");
  Object params[] = { "John" };
  String helloJohn = LocaleSupport.getLocalizedMessage(pageContext, "HelloName",params);  
%>
But the code above does not work in Google App Engine (run). What is worse - it works in development mode but after deploying to Google App Engine one gets into trouble. So it is not easy to recognize this issue, particularly in a larger project.

/notworkinghello.jsp
java.lang.NoClassDefFoundError: org/apache/taglibs/standard/tag/common/fmt/BundleSupport
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:143)
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:63)
 at org.apache.jsp.notworkinghello_jsp._jspService(notworkinghello_jsp.java:72)
......
What is more interesting, JSTL Code fmt:message tag is working as expected.
Solution
The only solution I found is to use BundleSupport class directly and create custom getMessage method.
It looks as below:
import java.text.MessageFormat;
import java.util.ResourceBundle;

import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;

import org.apache.taglibs.standard.tag.common.fmt.BundleSupport;

public class GetLocalizedMessage {

 /**
  * Replacement for LocaleSupport.getLocalizedMessage method in JSP pages
  * Before calling set fmt:setLocale and fmt: setBundle
  */
 
 private GetLocalizedMessage() {

 }

 /**
  * Gets localized message (also MessageFormated) from I18N bundle
  * @param pageContext PageContext
  * @param key Message key
  * @param params List of parameters for MessageFormat (if exists) 
  * @return localized message
  */
 public static String getMessage(PageContext pageContext, String key,
   String... params) {

  LocalizationContext loca = BundleSupport.getLocalizationContext(
    pageContext);
  ResourceBundle bundle = loca.getResourceBundle();
  String message = bundle.getString(key);
  if (params.length == 0) {
   return message;
  }
  String mess = MessageFormat.format(message, params);
  return mess;
 }

}

Then instead of getLocalizedMessage method from LocaleSupport class use method above directly - as source below.
<%
  String hello = GetLocalizedMessage.getMessage(pageContext, "Hello");
  String helloJohn = GetLocalizedMessage.getMessage(pageContext, "HelloName","John");
%>
The rest of the JSP page can be left without change. Finally the JSP page works as expected also in Google App Engine.
Source code 
The whole project is available here.

sobota, 7 kwietnia 2012

Byliśmy na koncercie

W dniu 1 kwietnia 2012 roku byliśmy na koncercie w ramach XVI Festiwalu Beethovenowskiego, podobało nam się bardzo. Sam koncert odbył się w pięknym wnętrzu Sali Wielkiej Zamku Królewskiego.
Hołdem złożonym dla patrona festiwalu było wykonanie Sonaty na wiolonczelę i fortepian D-dur op. 102 nr 2, ale to na pewno nie Beethoven było głównym bohaterem tego koncertu. Sam koncert wypełniła muzyka kompozytorów XX wiecznych, zaś zgodnie z intencją organizatorów koncertu motywem łączącym utwory była wojna i związki z wojną.
Ogromnie nam się podobał wykonany na koniec "Kwartet na koniec czasu" Oliviera Messiaena, tym bardziej że muzyka tego kompozytora nie tak często gości w Warszawie. Prawykonanie utworu odbyło się w okolicznościach niezwykłych, gdy kompozytor przebywał w obozie jenieckim w Zgorzelcu. Nadzorcy więzienni okazali się być miłośnikami muzyki, którzy umożliwili kompozytorowi pracę na utworem, zaś dobór instrumentów (klarnet, skrzypce, wiolonczela i fortepian na którym grał kompozytor) był wymuszony faktem, że akurat muzycy o takich specjalnościach odnaleźli się wśród współwięźniów. Poszczególne części utworu wykonywane są w różnym składzie, jedna część jest w całości wykonywana przez klarnet solo, są także części wykonywane przez same skrzypce z akompaniamentem fortepianu oraz podobnie wiolonczelę. Nie jestem specjalistą, ale wykonywać ten utwór muszą muzycy będący zarówno znakomitymi solistami jak i kameralistami.
Prawykonanie odbyło się 15 stycznia 1941 roku. Pamięć kompozytora po latach mnożyła liczbę więźniów będących słuchaczami czy ogrom trudności wykonawczych spowodowane kiepskim stanem instrumentów na których przyszło grać, ale utwór który powstał jest niezwykły i bardzo piękny, świadectwo czasów w jakich powstał, a także głębokiej wiary kompozytora.
Historia żołnierza Igora Strawińskiego to utwór bardzo znany, popularny i chętnie wykonywany. Zazwyczaj jest wykonywany w wersji koncertowej, często z dodaniem baletu i narracji. Ale, jak się przekonaliśmy, nic nie traci, a nawet zyskuje także w wersji kameralnej na klarnet, skrzypce i fortepian. A już na pewno, gdy wykonawcami są znakomici soliści, jak Kaja Danczowska na skrzypcach czy Michel Lethiec na klarnecie.
Dwa utwory Szostakowicza:  II Trio fortepianowe e-moll op. 67 oraz VIII Kwartet smyczkowy c-moll op. 110 także mają związek z wojną. Pierwszy został napisany w 1944, zaś po raz pierwszy wykonany w tym samym roku w Leningradzie , mieście niezwykle ciężko doświadczonym przez wojnę. Zaś drugi został napisany w 1960 roku i miał być muzyką do filmu o zbombardowaniu Drezna w 1945 roku. To muzyka bardzo efektowna, miejscami bardzo dynamiczna i głośna, miejscami wyciszona i spokojna. Pasjonujące było zwłaszcza obserwowanie wykonania pierwszej części II Tria fortepianowego, który zaczyna wiolonczela grająca solo.
Cały koncert trwał prawie cztery godziny, to był wspaniały wieczór. Jedyne co bym zmienił to dodanie jednak partii narracyjnej do "Historii żołnierza" Strawińskiego, bez tego rozumienie muzyki trochę traciło.  Wydłużyło by to tę cześć koncertu, ale można by zrezygnować z jednego z utworów Szostakowicza, zwłaszcza, że oba utwory są stylistycznie bardzo podobne, a nawet dzielą ze sobą ten sam temat muzyczny.

niedziela, 1 kwietnia 2012

Search and filter enhancement

General

I added simple enhancement to search and filter interface.
It is not easy to design a good search and filter mechanism. On one hand it should be powerful enough to allow the user to find what he/she needs, on the other it cannot be complicated because it would be rejected. So how to combine together effectiveness and usability. I don't mean that I'm in a possession of the magic formula but to my thinking the most convenient way is the "from - to" or "equal to" paradigm. Something like: "find all persons of age from 20 to 30" or "find all persons living in .. eg. find all persons whose place of residence is equal to ..".
Another approach to make the filter/searching mechanism as simple as possible is avoiding any additional improvement or modifiers (check or radio boxes) something like "in case of something cannot be found try something else" because it makes all stuff very complicated and finally it is not obvious what is looked for and what is found.
So I ended up with simple "from value" - "to value" schema without any buetyfiers.




















The formula is a simple as follows:
  • If neither "from" nor "to" value is entered then this field (attribute) is ignored during searching.
  • If only "from" value is enter ("to" remains empty) then mechanism picks up rows equal to the "to" value.
  • If both "from" and "to" values are entered then all rows between (inclusive) them are selected.
  • If only "to" value is entered ("from" remains empty) then all rows less or equal to the "to" value are selected.
  • All "from" - "to"  lines are participating in the query in "and" manner. For instance: if filter for "Symbol" attribute is used (meaning that either "from" or "to" value is not empty) and the same for "Nazwa" attribute then all rows passing both tests are selected.

To my experience that simple and intuitive mechanism is well appreciated by most users and enough in  most cases. Of course it is possible to enrich this schema by adding a lot of checboxes like ("and", "or", "equal", "less then") but it makes all stuff more complicated and does not bring many more value.

But, unfortunately, I was unable to keep to it any longer. Very often user needs to find something like "find all rows equal or greater than value" and this mechanism does not allow it. It is possible to put into "to" field very big value but it is artificial.
So I ended up with adding additional check box(GUI layout needs some improvements) :


The meaning of this additional check box is as follows.
If "from" value is entered and "to" value is empty then
  • If checkbox is checked then select all rows equal to the "from" value (default).
  • If check box is unchecked than find all rows equal or greater then "from" value.
 I'm not very happy with that because I had to break a rule (no single checkbox at all) but I was unable to find any other solution.

Demo version
Demo version is available here. The source code is available here. The data is persisted by means of Google App Engine for Java (JPA). The code for persistence layer and entity bean is also available.