Pages

Showing posts with label JEE. Show all posts
Showing posts with label JEE. Show all posts

Tuesday, March 29, 2011

Comparing different cache products

My app. relies heavily on cache to function. Although I use cache on the view, I use it mostly as Hibernate 2nd level cache. Here are some of the products I used and what I think about them.
Ehcache
I think this was used to be called Easy Hibernate Cache and Hibernate people promoted it's use. Now it's owned by Terracotta. I used this quite for a while, it's light, fast and mostly easy to use. However it didn't worked that good as a distributed cache environment.
It has multicast support for peer discovery which works pretty well for most of the time. Except it didn't worked on our prod environment where we have 10 nodes across the network. Some of the nodes just didn't connect to each other which is unacceptable.
It also has manual peer discovery, which needs different ehcache.xml's which would point to other nodes. I think you could tell hibernate, which xml to use at persistence.xml file.
Still I had hard time tracking which node joined to the cluster and which failed to.
Memcached
Main reason I tried memcached was, its use at facebook, wikipedia and such. Memcached is designed a bit different from the ehcache. This is written in 'C', had to be build and run as a daemon process. Cache clients can connect to it through telnet and perform. First problem I ran into was building it. Although It build easily on a Linux environment It required some editing to headers on a HP-UX in order to compile. Second and greater problem is, it doesn't have support for Hibernate. I used the library here http://code.google.com/p/hibernate-memcached/ which is not being actively developed anymore. It also has some nasty bugs...
Hazelcast
Hazelcast is what I use now. At first look it's design looks similar to ehcache but this one is made distribution in mind. It's distributed by default. I have enabled back-up reads, and near-cache settings for better performance.
It comes whit a decent monitoring app. which you can monitor your cluster and see the active nodes.
It's much easier to configure especially compared whit ehcache.

Wednesday, March 24, 2010

Hibernate Usage Strategy

Lately I got to refresh my hibernate knowledge. On previous posts I wrote about my experience with hibernate here and how things could get tangled up trying to load objects.
When using hibernate most important decision you have to make is how you are going to manage sessions. Basically you have to choose from a method scoped (service) session or conversation scoped long running sessions. My choice is here is to use the first one. While using a conversation scoped session might be easier to programmer downside is that database access could happen anywhere on your application uncontrolled. I think that could end you up, having to track down some performance bottlenecks, plus it means having a big object (session) in memory for some time.
Strategy
Not using a conversation scoped session forces you to determine an access strategy for your lazy associations. Note that you should still use these strategies even if you are using conversation scoped session, difference is it doesn't force you to.
Using Join Fetches
Joining usually gets omitted but it's the first thing to do. If you need lazy association, of a list of results, you have to join fetch them. Query below loads the cities with its parks:
 select c from City c join fetch c.parks
Of course if you need to list cities which don't have parks you have to use "left join fetch".
Caching
I remember reading, probably, on hibernate reference documentation something like caching is the last thing to do for performance. Now I think that I have underestimated using second level cache. Tables that hold rarely changing data should be loaded eagerly and cached. I also use a separate select to load them. This is how I mark such fields;
1:  @ManyToOne
2: @Fetch(FetchMode.SELECT)
3: CityType type;
This will force hibernate to cache the data upon first access.
Using a cache will generate much smaller queries and you wont have to write huge join statements to load lazy stuff.
I'll probably do more work using cache on an clustered environment.

Monday, February 15, 2010

What I been up to last couple of weeks

Day job kept quite busy last couple of weeks. Our new project is not managed in a agile way so after some months of preparing "big docs" we have finally hit the stage of coding. Just before starting to code, we have realised that we needed to change some of the architectural decisions we assumed and do some work on our code-base. We would have done that a lot earlier probably if we were on a agile route...
IDEs
We have decided to have 5 different applications that could be plugged in and out from each-other, formed by at least three modules; ejbs, ejb clients and a gui.
I found developing an app. made up of different modules in Eclipse quite limiting. You can't configure different web.xml's or persistence.xml's for different configurations you have.
IDEA9 on the other hand, has just what I had in my mind. It has a great artifacts screen where you can control where what configuration will go, which modules compile-output will go where and what jars to copy on what directory.Things I missed from Eclipse were the subclipse and Propedit plugins. Also on IDEA the run screen strangely only had "deploy all" button. To deploy my apps. seperately I needed to use autodeploy feature or the remote server setting. IDEA9 has 30 days of free evaluation period where you can test it. For now we are still bound to Eclipse but we might choose to use IDEA in the future.
Application Server
Another major change was since we needed an Application Server for ejbs we couldnt use the developer friendly Tomcat. I had a nice experience with GlassFishV3 server while doing the JEE6 projects, but our company would probably choose BEA's Weblogic. Every AS needs some twiks. Weblogic had some class loader problem with our app. which we needed to overcome by defining a weblogic-application.xml. Details could be found here. One last thing to note is, weblogic jndi look-upsi needs the qualified class names. Like if you have a mapped name of "my/MyService" you have to look it up with; "my/MyService#interfaceName..."
Lookups
GUI part of our app. is made of jsf & spring. I have used the springs LocalStatelessSessionProxyFactoryBean to lookup EJB's. It does it's job but I believe it has some missing features. It would be far more efficient, while developing, if I didn't had to restart my gui after my ejb's were deployed. On that case instead of performing the lookup again spring just throws an exception, though I think I could find a solution that does that.
Mentoring
Thats what I do mostly here. I started getting bored with that... From now on I think I will mostly just hit people behind their neck to point them to right direction.

Wednesday, December 16, 2009

Developing Custom Scopes/Contexts For Weld

This one came up while developing an example JEE6 project, which I'll add it up here in the future. The case is I had a textbox bound to a request scoped bean. When user triggers the paint action the value in the textbox is to be added to the list below and the textbox should be empty. I thought marking the component request scoped should have been enough to empty its values but it didn't.Apparently to empty the value;
1. I might set the value of the field at the action method. Use a clone for the list.
2. Use a JSF component that doesn't redisplay value after post back like the inputSecret.
3. Develop a custom scope that recreates it self after actions are invoked.
Anyway maybe I am missed a simpler solution but I chose number 3 :) .
To do that first thing is to create a new scope type. I called my scope the "ActionScoped":
1:  @NormalScope(passivating=false)
2: @Retention(RUNTIME)
3: @Target({TYPE, METHOD})
4: @Inherited
5: public @interface ActionScoped {
6: }
@NormalScope annotations marks an annotation as a scope-type. Next we need a context that would define when these action scoped objects exist like the request scope exist while there is a http request... This is the action context :
1:  import org.jboss.weld.context.AbstractThreadLocalMapContext;
2: import org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore;
3:
4: public class ActionContext extends AbstractThreadLocalMapContext {
5:
6: private static ActionContext instance = new ActionContext();
7:
8: private ActionContext() {
9: super(ActionScoped.class);
10: }
11:
12: public static ActionContext getInstance() {
13: return instance;
14: }
15:
16: @Override
17: protected boolean isCreationLockRequired() {
18: return false;
19: }
20:
21: public void activate() {
22: setActive(true);
23: setBeanStore(new ConcurrentHashMapBeanStore());
24: }
25:
26: public void deActivate() {
27: destroy();
28: setActive(false);
29: setBeanStore(null);
30: }
31:
32: public void reActivate() {
33: deActivate();
34: activate();
35: }
36: }
It's backed with an thread local object which is handled by the weld parent class. Bean store is where we are going to store the scoped beans. Plus I added some methods to activate (set a new bean store) /deactivate (destroy the bean store) the context. Now this context has to be activated with the start of the restore view.Deactivated and reactivated after the invoke application phase. Here is a phase listener that does that :
1:  public class ActionScopedPhaseListener implements PhaseListener {
2:
3: public void beforePhase(PhaseEvent event) {
4: if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
5: ActionContext.getInstance().activate();
6: }
7: }
8:
9: public void afterPhase(PhaseEvent event) {
10: if (event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
11: ActionContext.getInstance().deActivate();
12: } else if (event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
13: ActionContext.getInstance().reActivate();
14: }
15: }
16:
17:
18: public PhaseId getPhaseId() {
19: return PhaseId.ANY_PHASE;
20: }
21: }
22:
Now last thing we have to do is register our context object. In order to do that we need to define an 'extension'. There is a nice example here about extensions, spi... Without an extension we are not able listen to events fired from the weld container which we could use to add our new context object. To define an new context we need the META-INF/services/javax.enterprise.inject.spi.Extension file which contains the qualified name of our extensions class. In this case it's 'org.mca.ewall.extensions.Extensions'. Here is what the class looks like :
1:  public class Extensions implements Extension, Service{
2:
3: public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
4: event.addContext(ActionContext.getInstance());
5: }
6:
7: public void cleanup() {
8: }
9: }
It simply registers the context object after the application starts up (after the beans are discovered by the weld container). Now the beans could be annotated as @ActionScoped.

Wednesday, December 9, 2009

State of the 'Dependecy Injection'

"Dependecy Injection" is one of the most popular design patterns on the Java platform. It was suggested by Martin Fowler, here, instead of the term "Inversion of control". Article was published on 2004.
What it brings to a application is a way to create, compose, use and destroy any java object, which are called beans.
The leading framework that first used this approach was the "the Spring Framework". The approach emerged as a alternative to EJB's. The applications built with it are easier to test and offered a easy way to integrate to most of the other frameworks and technologies out there. If you check out the api packages you can see the support for other frameworks like jsf, hibernate etc.
Today "Dependecy Injection" is part of JEE6 named CDI, JSR-299. Reference implementation is called Weld. Here are some of the highlights of CDI:
XML vs. Annotations
CDI dumps the xml approach. However there are still some use for xml's. Every bean archive must have a META-INF/beans.xml even if its empty. This file marks the jar archive as a bean archive and is scanned for beans. 'beans.xml' is also where you enable and define the ordering of 'alternative' beans and interceptors.
Qualifiers
First thing that CDI takes to account while trying to inject a bean is the type of the bean. If however there are more than one bean that could qualify CDI requires a Qualifier meta-data to resolve the ambiguity. CDI has a way to define this meta-data as an annotation, thus making our app. strong typed apposed to the usual string based qualifier approach.
Events
By defining a few annotations we could implement the Observer pattern without any boilerplate code.
Decorators
Again with annotations we could implement the decorator pattern.
Part of JEE6
Now we could inject our beans to servlets and filters like we do to any other class.
Overall as far as I could tell CDI looks like it could improve an applications code quality making it decoupled and strong-typed. JEE6 still needs some time though, best implementation out there seems to be JBoss 6 Milestone 1.

Wednesday, October 21, 2009

Hibernate Journey

Now
So we have started our new project and by default (not my decision, not saying its a bad decision either, just saying that there could be a better decision) we are going to be using Hibernate.
For those who don't know Hibernate is 'the' ORM solution. ORM is for 'Object Relation Mapping' which is pretty much self explanatory. It maps your relational data model, such as a database schema, to the object model.
The Begining
Back in 2005 we started our project with Hibernate2. There were no annotations yet so we had to use XML files to map the object domain. So here is how the object domain looks like ;
 public class City {
private Long id;
private String name;
... more fields and getter / setters
Our object-domain is made of classes with complex (like other classes or lists...) or primitive (String, Long ...) fields and their getter / setter methods, which is called the 'POJO' (Plain Old Java Object). These POJOs will be representing the rows of a table. String's will be mapped to VARCHAR's on Oracle, complex types will be foreign keys to other tables. Of course we need to specify which POJO is related with which table or which field is mapped to what column. This is done in the mapping XML and here is how it might look like ;
 <class name="foo.City" table="CITY">
<id column="ID" name="id" type="java.lang.Long">
... some mechanism to generate id's
</id>
<property column="NAME" name="name" type="java.lang.String"/>
...
With this model we could save ( 'persist' ) our POJOs to databases with out us explicitly writing insert statements and query our object-domain with a special query language (similar to sql) HQL and get POJOs as result.
The Plugin
We were creating our POJOs through a class modeler (RSAs class diagram plugin) and we realised that we could write a plugin that could also generate the mapping XMLs. All we had to do was mark the class diagrams with some 'StereoType's that we have created;
The things with '<<...>>' are the stereotypes where we could add the table names and such through attributes.
The Evil
I was happily programming until I was told that we were to update to a newer version of Hibernate. Well after the update nothing worked :) . The main reson was that with this version all the relations were 'Lazy' by default (which is the correct way to work with hibernate by the way). To better understand the problem suppose that we are querying the City object. Now we might not be needing the Park's of the City so loading them since it will cause more selects or joins would not be desirable. This is what is trying to be achived with the 'Lazy'. Loading the partial object graph and loading the specific lazy relations only when required.
When we have a City with lazy parks we could load the parks at the time when its getter is called however the city object must have an open session (session is hibernate's transaction unit). If the hibernate session where the city object has been loaded was closed a LazyInitializationException is thrown. Here is a code piece which shows whats ok and whats not :
 session.open();
City aCity = session.load(City.class,1);
City anotherCity = session.load(City.class,2);
aCity().getParks(); <= OK to call parks here
session.commit();
session.close();
aCity().getParks(); <= Still OK to call parks here because its already initialized
anotherCity.getParks(); <= This will throw an exception !
The thing to note here is that Hibernate POJOs are not so 'Plain'. A POJO is actually wrapped with hibernate generated proxies to do the initializing when required. You should always think POJOs with the underlying session object. There are numerous patterns to manage the sessions like 'Session Per View', 'Session Per Conversation' pattern ... You should always think of the object graph you will be using and join the objects on your queries according to that.
5
With the Java 5 came the annotations and it replaced the need to have XMLs. XML is still supported but I don't see any reason why someone choose that to annotations. Here is how our POJO might look like with annotations:
 @Table(name="DIL")
@Entity
class City {
@Id
private Long id;
@Column(name="NAME")
private String name;
...
Back
Hibernate has a indexing integration (lucene) , a validation framework and caching frameworks. It should be used with care and respect :)

Tuesday, September 1, 2009

What should new JEE developers learn

We now started a new Enterprise project for Telecom and my first job is helping the new team get started. We are using, and seems will be using, the JSF, Spring and Hibernate technology stack. I am told that although some of them know some of the technologies we use, none know all.
So what should they learn and where to start;

JEE
  • The request & response lifecycle,
  • State on AS. How does Session works.
  • Servlet's and Filter's
  • JSPs, JSTLs and Custom Tags
  • A simple blogging application can be created with the above.
Spring Framework
  • The "Dependecy Injection" Pattern
  • Creating & managing Beans with Xml or Annotations
  • Proxying and Interceptors
  • JDBC Support
  • We can improve our app. with the above. Move the data to spring beans, and actually use database at this point.
  • Although we don't use the MVC it could be introduced here and see how much it will help with our app.
JSF
  • The components
  • JSF Lifecycle and how its manupilated with immediate attribute...
  • How facelets add to JSF
  • At this point we can improve app. with the JSF
  • Introduce the ajax and ajax enabled components
  • How to create custom JSF components
WebFlow
  • How state machine logic helps the navigation
  • New scopes the webflow introduces
  • Improve the app.
Hibernate
  • ORM concept
  • JPA annotations
  • Startegies to manage the hibernate session
  • Improve the app.
Reporting
  • We are using JasperReports which I don't know much about that at the moment :)
After this point I am thinking that new requirements could be introduced and the team could work on them as pairs. Pairs will be swapped often and there could be nightly reviews.
As for learning these one also needs some nice examples, one is mesir developed by my buddy Mert. It's a showcase of most of the technologies I wrote above.
For "Dependecy Injection" pattern Martin Fowler has this paper.
As for me Spring's and Hibernate's reference and api documentation is pretty solid.
For JSF Richard Hightower's "JSF for Non Believers" and "JSF fits facelets like glove" are quite fun to read articles.
On extreme programming practices here is a article at objectmentor site which demonstrates a session between two programmers.
Although pretty boring, working for sun certificates are helpful and good to learn the basics (SCJP and SCWCD).
These are what comes to my mind.

Thursday, May 28, 2009

seamy photo gallery, writing an authentication filter (part 5)

On the 4th part I used an simple authentication filter, to secure my urls, that come out of the box. It only supported basic & digest authentication. With basic authentication what you get is a ugly browser dependent box which asks the credentials of the user. On IE its like:
Instead of that I wanted the user to use the login page which I created. In order to do that I first removed basic authentication filter component and started coding mine :
@Scope(APPLICATION)
@Name("customAuthenticationFilter")
@Install(precedence = Install.DEPLOYMENT)
@BypassInterceptors
@Filter(within = "org.jboss.seam.web.exceptionFilter")
public class CustomAuthenticationFilter extends AbstractFilter {
@Logger
protected Log log;

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("This filter can only process HttpServletRequest requests");
}

HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpRequest.getSession();
Context ctx = new SessionContext(new ServletRequestSessionMap(httpRequest));
Identity identity = (Identity) ctx.get(Identity.class);
if (identity.isLoggedIn()) {
chain.doFilter(request, response);
}
else {
// go login than come back
httpResponse.sendRedirect("/seams/login?serviceUrl="
+ httpRequest.getRequestURL());
}

}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
setUrlPattern("/seam/resource/rest/*");
super.init(filterConfig);
}
}
Seam handles the creation and order of the filters with the help of @Filter annotation. Instead of adding web.xml entries we annotate our filters and specify where they should be in the filter chain. 
I have extended my filter from the seam AbstractFilter class and on the init method I setted the url pattern which the filter mappes to. 
On the doFilter method first thing to do is try to see if the user is already logged in. We have to access the Identity component but seams injections mechanism does not work with the filters. So instead of injecting you have to create a context (and such) to access the Identity component.
Once we have the Identity component we see if the user is already logged in. If so we proceed with the rest of the chain if not we redirect to our custom login page and pass the original page that the user tried to access with a request parameter that I named serviceUrl.
Once the user successfully logs in we need to redirect the user to original resouce pointed by the serviceUrl. To do that I wrote a Listener class which will fire after the user successfully logs in :
@Name("loginRedirect")
@Scope(ScopeType.SESSION)
public class LoginRedirectListener {
private String serviceUrl;

@Observer("org.jboss.seam.security.postAuthenticate")
public void postAuthentication() throws IOException {
if (serviceUrl != null && serviceUrl.length() > 0) {
FacesContext.getCurrentInstance().getExternalContext().redirect(serviceUrl);
}
}
...
The good old observer pattern is implement with annotations on seam. Here using the @Observer annotation we get notified of authentication event end redirect to the serviceUrl if there is one. I have created it as a session bean so that each user will his own serviceUrl. One last thing to do is injecting the serviceUrl parameter to my listener which is done through pages.xml:
<page view-id="/login.xhtml">
<rewrite pattern="/login" />
<param name="serviceUrl" value="#{loginRedirect.serviceUrl}"/>
</page>
Thats all there is...

Wednesday, May 27, 2009

seamy photo gallery, resting easier (part 4)

On my previous post I made a restful photo gallery that has a nice little feature where upon a restful request like 'http://.../mygallery/photo/photo/yoda' served the image named 'yoda' to the user. In order to achive that what I did was first I edited the pages.xml so that it could extract the name (id) part from the request url:
<page view-id="/photo/photo.xhtml" login-required="true">
<rewrite pattern="/photo/photo/{fotoId}" />
<param name="fotoId" value="{fotoId}" />
</page>
Here the name is extracted into el context as 'fotoId'. Second thing is that I created the photo.xhtml mentioned above:
<f:view>
<s:graphicImage id="imaj" value="#{photoService.getFoto(fotoId)}"
style="border: 1px solid black;" lt="image could not be found">
</s:graphicImage>
</f:view>
I used a 's:graphicImage' component which serves the photo using a little service bean using our 'fotoId' parameter. For completeness here is the service bean:
@Name("photoService")
@Scope(ScopeType.APPLICATION)
public class PhotoService {
public byte[] getFoto(String fotoId) {
Photo p = getPhoto(fotoId);
if (p == null) {
return null;
}
return p.getData();
}
...
What bugged me on this method was that although I just wanted the serve the image here I was actually serving a html page which linked to the image. 
After looking around I learned that what I wanted, came with the seam & resteasy integration. RESTEasy (jaxrs) comes with annotations where you can use to serve the result of methods & beans directly. Seam package comes with the required jars  (dont go downloading for a resteasy package from jboss.org) for integrating it. You just put them in your classpath. So inorder to serve my 'photoService.getFoto' I can use the @Get, @Path and other annotations :
@Name("photoService")
@Scope(ScopeType.APPLICATION)
@Path("/foto")
public class PhotoService {

@GET
@Path("/{fotoId}")
@ProduceMime("image/jpeg")

public byte[] getFoto(@PathParam("fotoId")
String fotoId) {
...
Rest access is by default configured under '.../seam/resource/rest/'. So by using the path and get annotions I can access the 'photoService.getFoto' method with the '.../seam/resource/rest/foto/yoda' request. ProduceMime annotation tells that we are serving an jpeg image and the PathParam annotation is used so that we can get the 'yoda' out of the request and used it as a parameter to our method.
Now are we done ? No, because we need to secure it!. We dont want Vader to see the comprimising images of the Yoda (hehe) so we need to secure it with the restrict annotation :
@GET
@Path("/{fotoId}")
@ProduceMime("image/jpeg")
@Restrict("#{s:hasRole('user') || s:hasRole('admin')}")
public byte[] getFoto(@PathParam("fotoId")
String fotoId) ...
Now what happens when someone not logged in tries to acces the yoda is we will see a NotLoggedInException on the stacktrace. Of course we need to handle that and give the user the option to log in. Seam has a 'web:authentication-filter' component that supports the http basic or digest authentication which I configured like this on components.xml:
<web:authentication-filter url-pattern="/seam/resource/rest/*"
auth-type="basic" />
Now the yoda is safe I guess and I am sure there will be different authentication types supported in the future. I got few that could be implemented like the oauth which I belive is used by twitter and such.

Monday, May 4, 2009

seamy photo gallery, securing it (part 3)

Previous part was about setting up security so that we have a admin user that could approve photos and an ordinary one. We have done basic authentication on this part we will look at handling authorization exceptions, securing our view and code based on authority.
First thing I did was adding approve and disapprove (delete the photo) methods to my photoService and make them authorized :
@Restrict("#{s:hasRole('admin')}")
public void approvePhoto(Photo p) {
logger.info("approving :" + p.getName());
p.approve();
entityManager.merge(p);
}

@Restrict("#{s:hasRole('admin')}")
public void disapprovePhoto(Photo p) {
logger.info("disapprovePhoto :" + p.getName());
entityManager.remove(getPhoto(p.getName()));
}
@Restrict annotation with the specified EL makes sure that user invoking these methods have admin right. Upon unauthorized access an authorization exception thrown which I handled in the pages.xml :
<exception class="org.jboss.seam.security.AuthorizationException">
<redirect>
<message>You don't have permission to do this</message>
</redirect>
</exception>
By doing so we will have an authorization exception message on our message component. There is a small issue I encountered however ; http://www.seamframework.org/Community/ExceptionInRedirectHandler
Next I added links to pics in the gallery that will invoke these actions. Seam has annatotions just for doing this kind of stuff on datatables. This is what my datatable looked liked : 
<rich:dataGrid value="#{photoService.frontPagePhotos}" var="foto"
columns="3" elements="9">
<h:column>
<s:div>
<s:link id="lnk_foto" view="/photo/photo.xhtml" propagation="none">
<f:param name="fotoId" value="#{foto.name}" />
<s:graphicImage id="imaj" value="#{foto.data}"
style="border: 1px solid black;" lt="image could not be found">
<s:transformImageSize width="100" maintainRatio="true" />
</s:graphicImage>
</s:link>
</s:div>
<s:div>
<h:outputLabel value="#{foto.name}" for="imaj" />
</s:div>
<s:div>
<h:commandLink value="Approve"
action="#{photoService.approvePhoto(foto)}"
rendered="#{foto.approved eq null}" />
<h:outputText value="," rendered="#{foto.approved eq null}" />
<h:commandLink value="Delete"
action="#{photoService.disapprovePhoto(foto)}"
rendered="#{s:hasRole('admin')}" />
</s:div>
</h:column>
</rich:dataGrid>
Approve and delete buttons must be rendered only with the user with the role admin #{s:hasRole('admin')} EL does that. 
The last thing I did was adding a logout method which is just :
<h:commandButton action="#{identity.logout()}" value="Logout" />

Again I encountered a litte problem with this : http://www.seamframework.org/Community/RedirectingWhereLeftAfterLogout . Thats all for now. Keep coding...

Wednesday, April 29, 2009

seamy photo gallery, securing it (part 2)

The new requirement that I wanted was "photos should be approved before being shown in the main page". For that I needed users with approving privledge or role, therefore it was time to dive in to the seam security part. I used simplest User and Role classes that I could think them and configured them :
<security:jpa-identity-store
user-class="domain.User"
role-class="domain.Role" />
Seam requires that you annotate your user domain and specify your username, password and other fields with annotations. Simplest model mostly from the reference :
public class User {
@Id
@UserPrincipal
private String login;

@UserPassword
private String password;

@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "USER_ROLE")
@UserRoles
private Set<Role> roles = new HashSet<Role>();
...
@Entity
public class Role {
@Id
@RoleName
private String name;
...
@Password annotation has the option to hash the data behind the scenes if you wish so. 
The next thing to the is authenticator method.
<security:identity
authenticate-method="#{authenticator.authenticate}" />
@Scope(ScopeType.APPLICATION)
@Name("authenticator")
public class Authenticator {

@In
EntityManager entityManager;

@In
Identity identity;

public boolean authenticate() {
try {
User u = (User) entityManager.createQuery(
"select u from User u where "
+ "u.login = #{credentials.username} and u.password = #{credentials.password}")
.getSingleResult();

CollectionUtils.forAllDo(u.getRoles(), new Closure() {
public void execute(Object objrole) {
Role role = (Role) objrole;
identity.addRole(role.getName());
}
});

return true;
}
catch (NoResultException ex) {
return false;
}
}

@Create
public void initTestUsers() {
entityManager.persist(new User("mca", "mca").addRole(new Role("user")));
entityManager.persist(new User("op", "op").addRole(new Role("admin")));
}

}
Authenticate method returns if the authentication is successfull or not. Credentials component is used to hold username and password of the user trying to login. If the authentication is successfull we also need to add the user roles to identity component. I have also used the @Create annotation so that I could create some test users when the component is created. The login page needs to get the values to credentials compenent and simply call the Identity.login method :
<h:inputText id="txt_username"
value="#{credentials.username}" ...
<h:inputSecret id="password"
value="#{credentials.password}" ...
<h:commandButton value="Login" action="#{identity.login}"/>
Up to this value we have done what is needed to authenticate a user. To secure our main page we need to mark it a page which needs login on pages.xml :
<pages login-view-id="/login.xhtml" ...

<page view-id="/photo/index.xhtml" login-required="true">
<rewrite pattern="/photo/index" />
</page>
Now when a user logs in he will be redirected to the login page specified in the pages tag. When the login is successfull to redirect the user to their original target page you can use the redirect component with the events:
<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}" />
</event>

<event type="org.jboss.seam.security.postAuthenticate">
<action execute="#{redirect.returnToCapturedView}" />
</event>
Will be continued...

Bulldozer coding

Jaroslav Tulach, designer of NetBeans API, defines the bulldozer coding as  instead of designing elegant solutions to problems at hand, you choose to use heavy libraries which are good for manythings in "Practical API Design". Which kind of reminds me of the Developer Jar Ratio that I wrote here.
Up side of the aproach is you are supposedly getting things done more quickly therefore increased productivity.
Apparent downside is that increased system resources needed for the application. The answer to that is buying memmory is cheaper than the developers time.
This approach apperntly works but still I don't think it is acceptable. My personel experience is that while you should use cluster of servers for your application you should also need powerful machines for your developers in order to get the developement time benefit. For example checking the hibernate forums lots of junior developers find out that they needed to extend "permanent heap size" the hard way. Again even with a powerful machine and hot deployment enabled server you will be restarting your machine a lot which is the faster the better. If you are using an api like hibernate which generates classes to do their trick and jvm with a permanent heap space, the more you restart your machine the more classes will be left in your memmory which means buy more RAM. The funny thing is as this is a developement problem it can be thoughted to be ignored.

Wednesday, April 22, 2009

more notes on seam

Here is more tips on seam;

  • I found out that blog example I wrote about has a little bit of history behind it. Apparently it was developed in response to a blog of Simon Brown. He publishes a set of blogger application requirements to compare web frameworks. Although Gavin argues that a blogger application hardly JEE, he still developes the example. Read more on it here http://relation.to/Bloggers/ComparingWebFrameworksSeam .
  • To validate against hibernate validators with JSF only thing you have to do is wrap the components with the "s:validateAll" tag. So if we have a name field in our page like;
    <s:validateAll>
    <h:inputText id="txt_name" value="#{newPhoto.name}" required="true" />
    </s:validateAll>
    Which is annotated like;
    @Length(max = 20)
    String name;
    "s:validateAll" tag will make sure nothing more than 20 characthers will pass and if tries to, a jsf error message will be raised. We could do all the basic validations but still not the required validation because, JSF does not call the validators if there is no value present...
  • Really liked the jboss el. You can even use it with ejb-ql's. Which is useful with standard seam components like the credentials component. This example is to check the credentials of a user: 
    User u = (User) entityManager.createQuery(
    "select u from User u where "
    + "u.login = #{credentials.username} and u.password = #{credentials.password}")
    .getSingleResult();
    A little DSL and we don't have to do more method chaining to pass the parameters. You can also use the EL with some  security annotations and possibly on more places...
  • It's not beans with seam. They call it components. And you can configure, add and remove them through components.xml . You can inject variables to your components with out the scope limit. And components can outject variables.
  • To configure components seam people chose to make a API of annotations instead of defining interfaces like the spring api has. I am not sure if the spring api has something new but this is what you used do if you needed a method to run after a bean has been created;
    public class SomeBean implements InitializingBean, ... {
    ...
    public void afterPropertiesSet() throws Exception {
    ...
    That is you have to implement the InitializingBean interface. On seam you have to annotate a method with the @Create annotation:
    @Create
    public void initTestUsers() {
    ...
    I personally liked the annotation approach better in a language perspective, but I guess its harder to implement and will depend on reflection api, so will be slower.
  • Another thing was my toy app was not working yesterday. It turned out that it could not access the dtd's in xml definitions because jboss was on maintainnance so I deleted them from xml's...

Wednesday, April 15, 2009

little restfull photo gallery example, with seam, which seams fine

I have decided it was time to check out the seam framework since many of my friends gave it a thumbs up. Starting with the blog example that comes with the package I have built a little restfull image gallery. Which looked liked this;
I started with a simple Photo domain object which has name as the id, and the data byte array as the photo file:
@Entity
@Name("newPhoto")
@Scope(ScopeType.SESSION)
public class Photo {
@Id
String name;
byte[] data;
...
}
Whats seamy here is the @Name and the @Scope annotations. @Name annotation declares named beans of the type. In this case I created one to use to hold the user submitted information. @Scope annotation declares the scope of the bean in this case I will use one bean for every session.
Then the action methods to persist and retrieve the photos:
@Name("pholog")
public class PhotoService {
@In
private EntityManager entityManager;
public List<Photo> getFrontPagePhotos() {
...
public byte[] getFoto(String fotoId) {
...
public void createNewPhoto(Photo p) {
if (p.getData() != null) {
try {
entityManager.persist(p);
}
catch (PersistenceException pe) {
FacesMessages.instance().add("Data exists!");
}
}
else {
FacesMessages.instance().add("File is required!");
}
}
}
The @In annotation injects other beans to our new bean. On the createNewPhoto method I do some validations and add validation errors if needed which I suppose a declarative syntax might exist that I don't know about.
On the view side seams comes with some extra tags that standard JSF does not have like the, fileUpload tag, or a better integrated graphicImage compenent. Nevertheless I had to add the richfaces package since I didn't like the way the standard datatable looks and behaves.
My form to upload a Photo:
    <h:form enctype="multipart/form-data">
<span class="errors"><h:messages /></span>
<h:panelGrid columns="2">
<h:outputLabel value="Name" for="txt_name" />
<h:inputText id="txt_name" value="#{newPhoto.name}" required="true"
requiredMessage="Name is required!" />
<h:outputLabel value="File" for="flu_dosya" />
<s:fileUpload id="flu_dosya" data="#{newPhoto.data}" />
</h:panelGrid>
<h:commandButton action="#{pholog.createNewPhoto(newPhoto)}"
value="Create" />
</h:form>
Tricky thing about the fileUpload was that you have to mark your form as "multipart/form-data" otherwise nothing gets uploaded. I am not sure if this is just a seam thing or a JSF spec thing. Another important feature here is #{pholog.createNewPhoto(newPhoto)} el expression which glues the domain and the action beans we have declared. I used to do something similiar using ognl expressions now it comes out of the box. 
Part that displays the gallery:
    <rich:dataGrid value="#{pholog.frontPagePhotos}" var="foto" columns="3"
elements="9">
<h:column>
<s:div>
<s:link id="lnk_foto" view="/photo/photo.xhtml" propagation="none">
<f:param name="fotoId" value="#{foto.name}" />
<s:graphicImage id="imaj" value="#{foto.data}"
style="border: 1px solid black;" lt="image could not be found">
<s:transformImageSize width="100" maintainRatio="true" />
</s:graphicImage>
</s:link>
</s:div>
I used the rich:dataGrid component which gives me nice 3x9 grid to display my images. seams graphicImage component converts the photo byte [] to a resource link which is served. In order it to work you have to add the Seam Resource Servlet to your web.xml;
    <servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>
org.jboss.seam.servlet.SeamResourceServlet
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
The s:link component links the thumbnail to photo.xml page where the image will be displayed with a restful url. My photo.xhtml is simply like;
<f:view>
<s:graphicImage id="imaj" value="#{pholog.getFoto(fotoId)}"
style="border: 1px solid black;" lt="image could not be found">
</s:graphicImage>
</f:view>
It has a graphicImage component with no transformations and gets the foto with the fotoId parameter. In order this to work and have urls like /examplegallery/photo/photo/yoda to display the image with the name yoda you have to make one last configuration in the pages.xml file;
    <page view-id="/photo/photo.xhtml">
<rewrite pattern="/photo/photo/{fotoId}" />
<param name="fotoId" value="{fotoId}" />
</page>
Here we are creating meaningful urls that could be bookmarked. In this case its like the page, photo, whit the foto name (photo id). And our page used the id (name) to retrieve and serve the image.
And for the last, things that I am curious about seam;
  • pages.xml file had to be seperate files since one file could easily go up to thounds of lines in a real project which won't be manageable. Or there might be a way that dumps the use of that xml file.
  • I am not entirely sure what the component.xml file does...
  • There could be a easier and better way to handle validations and display JSF exception that includes handling hibernate exceptions, validations.
  • Got to check out the seams conversation and navigation features.
  • Do a example with the bijection feature.
Those are my first impressions about seam I have added most of the code I added to the blog example here. So rest of the configuration is there.

Wednesday, March 11, 2009

Use OGNL expressions to fill your SelectOneMenu

JSF selectOneMenu component is loaded with "selectItems" tag. Like; 
<h:selectOneMenu id="som_city" value="#{valueObject.city}">
<t:selectItems value="#{cityService.getCities}" itemLabel="#{val.name}" itemValue="#{val.this}" var="val" />
</h:selectOneMenu>
With the help of some converter we are able to list cities in the combo with the expression "#{cityService.getCities}". But often what we realy want to do is list the cities of certain country which is perhaps choosen from another combo. What we need is another expression like "#{cityService.getCities(someCountry)}". 
To achive this I have overriden the myfaces UISelectItems and gave it the power of Ognl expressions:
import java.util.AbstractMap;
import java.util.HashSet;
import java.util.Set;

import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;

import ognl.Ognl;
import ognl.OgnlException;

import org.apache.myfaces.custom.selectitems.UISelectItems;

public class UISelectSmarterItems extends UISelectItems {

private String expString;

public String getExpString() {
if (expString != null)
return expString;

ValueBinding vb = getValueBinding("expString");
String v = vb != null ? (String) vb.getValue(getFacesContext()) : null;
return v;
}

public void setExpString(String expString) {
this.expString = expString;
}

@Override
public Object getValue() {
String str = getExpString();
if (str != null && str.length() > 0) {
setValue(evaluateExpression(str));
}

return super.getValue();
}

private Object evaluateExpression(String aExp) {
try {
return Ognl.getValue(aExp, new FacesEvaluationContext());
}
catch (OgnlException e) {
throw new RuntimeException(aExp);
}
}

private final class FacesEvaluationContext extends AbstractMap {

@Override
public Object get(Object key) {
return resolveVariable(key);
}

private Object resolveVariable(Object key) {
return getFacesContext().getApplication().createValueBinding("#{" + key + "}").getValue(getFacesContext());
}

@Override
public Set entrySet() {
return new HashSet();
}
}

@Override
public Object saveState(FacesContext context) {
Object values[] = new Object[2];
values[0] = super.saveState(context);
values[1] = expString;
return ((Object) (values));
}

@Override
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
expString = (String) values[1];
}

}
What I did is add expString property and give it the power of Ognl expression. In the end we are able write this;
<injsf:selectItems expString="cityService.getCities(someCity)"
var="val" itemLabel="#{val.name}" itemValue="#{val.this}"
/>

Smart JSF DataTable Columns

One of the common  and simple requirements of enterprise projects is that stylising your columns based on the data it contains like if the column is displaying a date it should be centered, if its a number it should be aligned right. The following will show you how you can make a smart enough datatable which knows what type needs what style.
I did this on the richfaces datatable but same logic could be used with other datatables.
1. Define the renderer
Since we are using rich faces we need to override the default renderer it comes with:
    <renderer>
<component-family>org.richfaces.Column</component-family>
<renderer-type>
org.richfaces.renderkit.CellRenderer
</renderer-type>
<renderer-class>
org.mca.example.web.renderkit.html.CellAutoAlignedRenderer
</renderer-class>
</renderer>
render-class tag is now CellAutoAlignedRenderer which we will implement.
2. Define the Renderer
The default rich faces renderer is org.richfaces.renderkit.CellRenderer.
We could achive the desired effect by simply overriding the
public String styleClass(FacesContext context, UIComponent component)
method.
import org.richfaces.renderkit.CellRenderer;

public class CellAutoAlignedRenderer extends CellRenderer {

@Override
public String styleClass(FacesContext context, UIComponent component) {
ValueExpression styleExpression = component.getValueExpression("styleClass");
if (styleExpression == null) {
Object value = getValueOfTheOnlyChild(context, component);
if (value instanceof Number) {
return super.styleClass(context, component) + " " + getNumberColumnStyle();
}
else if (value instanceof Date) {
return super.styleClass(context, component) + " " + getDateColumnStyle();
}
}
return super.styleClass(context, component);
}

public String getDateColumnStyle() {
return "dateColumn";
}

public String getNumberColumnStyle() {
return "numberColumn";
}

private Object getValueOfTheOnlyChild(FacesContext context, UIComponent component) {
if (component.getChildCount() == 1) {
UIComponent child = component.getChildren().get(0);
if (child instanceof ValueHolder) {
ValueHolder aValue = (ValueHolder) child;
return aValue.getValue();
}
}
return null;
}

}

"getValueOfTheOnlyChild" method gets the data from the column to determine the data type. "if (value instanceof Number) {" part does determines the style.
"copy paste"