Pathway from ACEGI to Spring Security 2.0

Formerly called ACEGI Security for Spring, the re-branded Spring Security 2.0 has delivered on its promises of making it simpler to use and improving developer productivity. Already considered as the Java platform’s most widely used enterprise security framework with over 250,000 downloads from SourceForge, Spring Security 2.0 provides a host of new features.

This article outlines how to convert your existing ACEGI based Spring application to use Spring Security 2.0.


What is Spring Security 2.0


Spring Security 2.0 has recently been released as a replacement to ACEGI and it provides a host of new security features:



  • Substantially simplified configuration.

  • OpenID integration, single sign on standard.

  • Windows NTLM support, single sign on against Windows corporate networks.

  • Support for JSR 250 (“EJB 3”) security annotations.

  • AspectJ pointcut expression language support.

  • Comprehensive support for RESTful web request authorization.

  • Long-requested support for groups, hierarchical roles and a user management API.

  • An improved, database-backed “remember me” implementation.

  • New support for web state and flow transition authorization through the Spring Web Flow 2.0 release.

  • Enhanced WSS (formerly WS-Security) support through the Spring Web Services 1.5 release.

  • A whole lot more…

Goal


Currently I work on a Spring web application that uses ACEGI to control access to the secure resources. Users are stored in a database and as such we have configured ACEGI to use a JDBC based UserDetails Service. Likewise, all of our web resources are stored in the database and ACEGI is configure to use a custom AbstractFilterInvocationDefinitionSource to check authorization details for each request.
With the release of Spring Security 2.0 I would like to see if I can replace ACEGI and keep the current ability to use the database as our source of authentication and authorization instead of the XML configuration files (as most examples demonstrate).


Here are the steps that I took…


Steps



  1. The first (and trickiest) step was to download the new Spring Security 2.0 Framework and make sure that the jar files are deployed to the correct location. (/WEB-INF/lib/)
    There are 22 jar files that come with the Spring Security 2.0 download. I did not need to use all of them (especially not the *sources packages). For this exercise I only had to include:


    • spring-security-acl-2.0.0.jar


    • spring-security-core-2.0.0.jar


    • spring-security-core-tiger-2.0.0.jar


    • spring-security-taglibs-2.0.0.jar

  2. Configure a DelegatingFilterProxy in the web.xml file.




    1. <filter>  

    2.     <filter-name>springSecurityFilterChain</filter-name>  

    3.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  

    4. </filter>  

    5. <filter-mapping>  

    6.     <filter-name>springSecurityFilterChain</filter-name>  

    7.     <url-pattern>/*</url-pattern>  

    8. </filter-mapping>  

  3. Configuration of Spring Security 2.0 is far more concise than ACEGI, so instead of changing my current ACEGI based configuration file, I found it easier to start from a empty file. If you do want to change your existing configuration file, I am sure that you will be deleting more lines than adding.

    The first part of the configuration is to specifiy the details for the secure resource filter, this is to allow secure resources to be read from the database and not from the actual configuration file. This is an example of what you will see in most of the examples:




    1. <http auto-config=“true” access-denied-page=“/403.jsp”>  

    2.     <intercept-url pattern=“/index.jsp” access=“ROLE_ADMINISTRATOR,ROLE_USER”/>  

    3.     <intercept-url pattern=“/securePage.jsp” access=“ROLE_ADMINISTRATOR”/>  

    4.     <intercept-url pattern=“/**” access=“ROLE_ANONYMOUS” />  

    5. </http>  
    Replace this with:




    1. <authentication-manager alias=“authenticationManager”/>  

    2.       

    3. <beans:bean id=“accessDecisionManager” class=“org.springframework.security.vote.AffirmativeBased”>  

    4.     <beans:property name=“allowIfAllAbstainDecisions” value=“false”/>  

    5.     <beans:property name=“decisionVoters”>  

    6.         <beans:list>  

    7.             <beans:bean class=“org.springframework.security.vote.RoleVoter”/>  

    8.             <beans:bean class=“org.springframework.security.vote.AuthenticatedVoter”/>  

    9.         </beans:list>  

    10.     </beans:property>  

    11. </beans:bean>  

    12.   

    13. <beans:bean id=“filterInvocationInterceptor” class=“org.springframework.security.intercept.web.FilterSecurityInterceptor”>  

    14. <beans:property name=“authenticationManager” ref=“authenticationManager”/>  

    15.     <beans:property name=“accessDecisionManager” ref=“accessDecisionManager”/>  

    16.     <beans:property name=“objectDefinitionSource” ref=“secureResourceFilter” />  

    17. </beans:bean>  

    18.       

    19. <beans:bean id=“secureResourceFilter” class=“org.security.SecureFilter.MySecureResourceFilter” />  

    20.   

    21. <http auto-config=“true” access-denied-page=“/403.jsp”>  

    22.     <concurrent-session-control max-sessions=“1” exception-if-maximum-exceeded=“true” />  

    23.     <form-login login-page=“/login.jsp” authentication-failure-url=“/login.jsp” default-target-url=“/index.jsp” />  

    24.     <logout logout-success-url=“/login.jsp”/>  

    25.  </http>  

    The main part of this piece of configuration is the secureResourceFilter, this is a class that implementsFilterInvocationDefinitionSource and is called when Spring Security needs to check the Authorities for a requested page.
    Here is the code for MySecureResourceFilter:




    1. package org.security.SecureFilter;  

    2.   

    3. import java.util.Collection;  

    4. import java.util.List;  

    5.   

    6. import org.springframework.security.ConfigAttributeDefinition;  

    7. import org.springframework.security.ConfigAttributeEditor;  

    8. import org.springframework.security.intercept.web.FilterInvocation;  

    9. import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;  

    10.   

    11.   

    12. public class MySecureResourceFilter implements FilterInvocationDefinitionSource {  

    13.   

    14.     public ConfigAttributeDefinition getAttributes(Object filter) throws IllegalArgumentException {  

    15.           

    16.         FilterInvocation filterInvocation = (FilterInvocation) filter;  

    17.           

    18.         String url = filterInvocation.getRequestUrl();  

    19.           

    20.         // create a resource object that represents this Url object  

    21.         Resource resource = new Resource(url);  

    22.           

    23.         if (resource == nullreturn null;  

    24.         else{  

    25.             ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();  

    26.             // get the Roles that can access this Url  

    27.             List<Role> roles = resource.getRoles();  

    28.             StringBuffer rolesList = new StringBuffer();  

    29.             for (Role role : roles){  

    30.                 rolesList.append(role.getName());  

    31.                 rolesList.append(“,”);  

    32.             }  

    33.             // don’t want to end with a “,” so remove the last “,”  

    34.             if (rolesList.length() > 0)  

    35.                 rolesList.replace(rolesList.length()-1, rolesList.length()+1“”);  

    36.             configAttrEditor.setAsText(rolesList.toString());  

    37.             return (ConfigAttributeDefinition) configAttrEditor.getValue();  

    38.         }         

    39.     }  

    40.   

    41.     public Collection getConfigAttributeDefinitions() {  

    42.         return null;  

    43.     }  

    44.   

    45.     public boolean supports(Class arg0) {  

    46.         return true;  

    47.     }  

    48.   

    49. }  
    This getAttributes() method above essentially returns the name of Authorities (which I call Roles) that are allowed access to the current Url.

  4. OK, so now we have setup the database based resources and now the next step is to get Spring Security to read the user details from the database. The examples that come with Spring Security 2.0 shows you how to keep a list of users and authorities in the configuration file like this:




    1. <authentication-provider>  

    2.     <user-service>  

    3.     <user name=“rod” password=“password” authorities=“ROLE_SUPERVISOR, ROLE_USER” />  

    4.     <user name=“dianne” password=“password” authorities=“ROLE_USER,ROLE_TELLER” />  

    5.     <user name=“scott” password=“password” authorities=“ROLE_USER” />  

    6.     <user name=“peter” password=“password” authorities=“ROLE_USER” />  

    7.     </user-service>  

    8. </authentication-provider>  
    You could replace these examples with this configuration so that you can read the user details straight from the database like this:




    1. <authentication-provider>  

    2.     <jdbc-user-service data-source-ref=“dataSource” />  

    3. </authentication-provider>  
    While this is a very fast and easy way to configure database based security it does mean that you have to conform to a default databases schema. By default, the <jdbc-user-service> requires the following tables: user, authorities, groups, group_members and group_authorities.
    In my case this was not going to work as my security schema it not the same as what the <jdbc-user-service>requires, so I was forced to change the <authentication-provider>:




    1. <authentication-provider>  

    2.     <jdbc-user-service data-source-ref=“dataSource”  

    3.     users-by-username-query=“SELECT U.username, U.password, U.accountEnabled AS ‘enabled’ FROM User U where U.username=?”  

    4.     authorities-by-username-query=“SELECT U.username, R.name as ‘authority’ FROM User U JOIN Authority A ON u.id = A.userId JOIN Role R ON R.id = A.roleId WHERE U.username=?”/>  

    5. </authentication-provider>  
    By adding the users-by-username-query and authorities-by-username-query properties you are able to override the default SQL statements with your own. As in ACEGI security you must make sure that the columns that your SQL statement returns is the same as what Spring Security expects. There is a another property group-authorities-by-username-query which I am not using and have therefore left it out of this example, but it works in exactly the same manner as the other two SQL statements.

    This feature of the <jdbc-user-service> has only been included in the past month or so and was not available in the pre-release versions of Spring Security. Luckily it has been added as it does make life a lot easier. You can read about this here and here.

    The dataSource bean instructs which database to connect to, it is not included in my configuration file as it’s not specific to security. Here is an example of a dataSource bean for those who are not sure:




    1. <bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>  

    2.     <property name=“driverClassName” value=“com.mysql.jdbc.Driver”/>  

    3.     <property name=“url” value=“jdbc:mysql://localhost/db_name?useUnicode=true&characterEncoding=utf-8”/>  

    4.     <property name=“username” value=“root”/>  

    5.     <property name=“password” value=“pwd”/>  

    6. </bean>  

  5. And that is all for the configuration of Spring Security. My last task was to change my current logon screen. In ACEGI you could create your own logon <form> by making sure that you POSTED the correctly named HTML input elements to the correct URL. While you can still do this in Spring Security 2.0, some of the names have changed.
    You can still call your username field j_username and your password field j_password as before.




    1. <input type=“text” name=“j_username” id=“j_username”/>  

    2. <input type=“password” name=“j_password” id=“j_password”/>  
    However you must set the action property of your <form> to point to j_spring_security_check and notj_acegi_security_check.




    1. <form method=“post” id=“loginForm” action=“<c:url value=’j_spring_security_check’/>”  
    There are a few places in our application where the user can logout, this is a link that redirects the logout request to the security framework so that it can be handled accordingly. This needs to be changed from j_acegi_logout toj_spring_security_logout.




    1. <a href=‘<c:url value=”j_spring_security_logout”/>’>Logout</a>  

Conclusion


This short guide on how to configure Spring Security 2.0 with access to resources stored in a database does not come close to illustrating the host of new features that are available in Spring Security 2.0, however I think that it does show some of the most commonly used abilities of the framework and I hope that you will find it useful.

One of the benefits of Spring Security 2.0 over ACEGI is the ability to write more consice configuration files, this is clearly shown when I compare my old ACEGI configration (172 lines) file to my new one (42 lines).
Here is my complete securityContext.xml file:





  1. <?xml version=“1.0” encoding=“UTF-8”?>  

  2. <beans:beans xmlns=“http://www.springframework.org/schema/security”   

  3. xmlns:beans=“http://www.springframework.org/schema/beans”   

  4. xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”   

  5. xsi:schemaLocation=“http://www.springframework.org/schema/beans,http://www.springframework.org/schema/beans/spring-beans-2.0.xsd,http://www.springframework.org/schema/security,http://www.springframework.org/schema/security/spring-security-2.0.xsd”> <authentication-manager alias=“authenticationManager”/>  <beans:bean id=“accessDecisionManager” class=“org.springframework.security.vote.AffirmativeBased”> <beans:property name=“allowIfAllAbstainDecisions” value=“false”/> <beans:property name=“decisionVoters”> <beans:list> <beans:bean class=“org.springframework.security.vote.RoleVoter”/> <beans:bean class=“org.springframework.security.vote.AuthenticatedVoter”/> </beans:list> </beans:property> </beans:bean> <beans:bean id=“filterInvocationInterceptor” class=“org.springframework.security.intercept.web.FilterSecurityInterceptor”> <beans:property name=“authenticationManager” ref=“authenticationManager”/> <beans:property name=“accessDecisionManager” ref=“accessDecisionManager”/> <beans:property name=“objectDefinitionSource” ref=“secureResourceFilter” /> </beans:bean>  <beans:bean id=“secureResourceFilter” class=“org.security.SecureFilter.MySecureResourceFilter” /> <http auto-config=“true” access-denied-page=“/403.jsp”>  <concurrent-session-control max-sessions=“1” exception-if-maximum-exceeded=“true” /> <form-login login-page=“/login.jsp” authentication-failure-url=“/login.jsp” default-target-url=“/index.jsp” /> <logout logout-success-url=“/login.jsp”/> </http>  <beans:bean id=“loggerListener” class=“org.springframework.security.event.authentication.LoggerListener”/>  <authentication-provider> <jdbc-user-service data-source-ref=“dataSource” users-by-username-query=“SELECT U.username, U.password, U.accountEnabled AS ‘enabled’ FROM User U where U.username=?” authorities-by-username-query=“SELECT U.username, R.name as ‘authority’ FROM User U JOIN Authority A ON u.id = A.userId JOIN Role R ON R.id = A.roleId WHERE U.username=?” /> </authentication-provider> </beans:beans>  

As I said in step 1, downloading Spring Security was the trickiest step of all. From there on it was plain sailing…

Google Android Tutorial

Google has recently released the Android platform for developing mobile applications. The language used for developing Android programs is Java, but it is not Java Micro Edition.  No wireless application developer can ignore  Android. Google is the best known brand name, among the users of the web and Android comes from Google. 


I am presenting this hands-on tutorial, as a sequel to my j2me series. Adequate knowledge of core-java ,especially Event-handling, Swing and inner-classes is assumed. Though Android does not make use of Swing, it uses  similar ideas.


We can develop Android lessons and applications in Eclipse environment. Google have provided an Eclipse-plugin for Android. This is the popular method. Google has not given direct support to Netbeans. But some Netbeans users have developed a method for running Android in Netbeans . It is available at  http://undroid.nolimit.cz/. You can find more screenshots and guidance in http://eppleton.com/blog/.


We can develop Android lessons without using either Eclipse or Netbeans. The necessary command-line tools have been provided by Google. I found that using these command-line tools is easier than either Eclipse or Netbeans method. So, I am basing all the following lessons on these tools. I think, most readers will agree with my view, after they try this method as well as Eclipse method. The Android site at ‘code.google.com/android’ has already given step-by-step instructions about Android in Eclipse. You can also get more details with screen shots from  a wonderful website at www.tanguay.info/web/welcome.php titled ‘Edward’s Web Developer site’. He gives excellent guidance with plenty of screen shots 


The Android site lacks clarity about the command-line method. Hence, I think I am adding something useful by writing on the command-line method instead of simply repeating the material in Android site.
Let us start from the beginning. The first step is downloading the Android SDK (version m5-rc14, Feb-12, 2008). Android was released in November, 2007 . It has been revised in the Feb-2008 version.Some of the earlier examples may not work in the newer version.


I am working in Windows-2000 and so I downloaded the windows version. The supported platform in Windows is either Windows-XP or Vista.(Mac OS 10 & Ubuntu Linux are the other platforms mentioned). However, it works well in my Win-2000. It is advisable to have at least 512MB memory. The android SDK is a zip file. I unzipped it to C:\unzipped\android and later, I copied that folder to D:\android. If you want, you can simply copy it to another drive like G:\android also. In the following lessons D:\android is used.


If you want to develop using Eclipse, you must have installed either Eclipse3.2 or Eclipse3.3(Europa). I have tested with Eclipse3.2. No problem.It works. But, we require ADT  (ie) Android Development Tools plugin for Eclipse, if you are using Eclipse.You can get this plugin from http://code.google.com/android/adt_download. You have to be careful about the ADT version number.It is ADT-0.3.3.



As my present focus is on command-line method, let me begin straight away and give a simple demo.The procedure given here is common for all our experiments and so I will not be repeating it in each demo. So, please note it down carefully.


Demo 1 – TextBox


In my first demo, I will have a customary button and textbox ( called EditField in Android). When I click the button, I want the message “SUCCESS!” to be displayed in textbox. Just as an exercise, I am using two buttons and two textboxes.



The first step is to start the Emulator


cd to d:\android\tools

d:\android\tools>emulator


It will take a long time to get started. Do not be in a hurry. Wait till it gets fully started. And do not  close that window carelessly by mistake. In that case, you will have to start it again and wait for a long time again. Finally, we get the emulator screen
 


The second step is to give the following command, from another command window.


d:\android\tools>

activityCreator –out  demo                                   mypack.mydemos.demo


This means that my project is ‘demo’ and my package is ‘mypack.mydemos’. A number of folders are created automatically by this command:



  • tools\demo\src
  • tools\demo\bin
  • tools\demo\res.  

We need to note  the src and res folders carefully. We will place the java source file in src folder and main.xml file in res\layout, overwriting any files that are generated automatically. For the moment, we can think of the res\layout folder as the one which decides the gui design. As in asp.net, flex etc, the gui details are specified in xml file. But how shall we write the XML file? by hand? Not too difficult .But….luckily, there is an open-source gui designer named ‘DroidDraw’ available in http://www.droiddraw.org/ .It is a nice tool and if you like it, you can send your appreciation to [email protected]. He has given a simple tutorial too, on how to use this gui tool.


I downloaded this software from the above site. I unzipped it. ( any folder). When we click on the icon, we get the screen as given below.


Droid DrawDroid Draw


 


Drawing Canvas AreaDrawing Canvas Area



Toolbox &amp; Blank AreaToolbox & Blank Area 


Thus we get a window, showing the drawing canvas on leftside and toolbox and a blank area in the rightside. ( for printing purpose, I have split them into two screens) as above.



From the toolbox, we learn that we are having controls like button,check,radio,spinner,edittext(textbox) and  textview (label) etc. There is also a combo  to choose  layout, in the canvas screen.  I am choosing ‘absolute layout’. I simply drag and drop a button and an editview on the canvas.(Drag and drop, do not click and drop! It won’t work).


You will notice a number of tabs in toolbox. Select ‘properties’ tab.. After clicking the button on the canvas, give the id property of button as @id/button1. Similarly, for editview as @id/text1. Also, button2 and text2 After this, just click the ‘generate’ button at the bottom of  the blank window. We get the following XML file(main.xml) automatically generated.





  1. <?xml version=“1.0” encoding=“utf-8”?>  

  2. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”  

  3.     android:layout_width=“fill_parent” android:layout_height=“wrap_content”  

  4.     android:padding=“10px”>  

  5.     <EditText android:id=“@+id/text1” android:layout_width=“fill_parent”  

  6.         android:layout_height=“wrap_content” />  

  7.     <Button android:id=“@+id/button1” android:layout_width=“wrap_content”  

  8.         android:layout_height=“wrap_content” android:layout_below=“@id/text1”  

  9.         android:layout_alignParentRight=“true” android:layout_marginLeft=“10px”  

  10.         android:text=“click” />  

  11.     <EditText android:id=“@+id/text2” android:layout_width=“fill_parent”  

  12.         android:layout_height=“wrap_content” android:layout_below=“@id/button1” />  

  13.     <Button android:id=“@+id/button2” android:layout_width=“wrap_content”  

  14.         android:layout_height=“wrap_content” android:layout_below=“@id/text2”  

  15.         android:layout_alignParentRight=“true” android:layout_marginLeft=“10px”  

  16.         android:text=“click” />  

  17. </RelativeLayout>  

We can now create our java source file. The code refers to main.xml for id of the controls.
(d:\android\mydemos\ex1\demo.java).This is our work folder.





  1. package mypack.mydemos;   

  2.   

  3.   

  4. import android.app.Activity;   

  5. import android.os.Bundle;   

  6. import android.view.View;   

  7. import android.widget.*;   

  8.   

  9.   

  10. public class demo extends Activity     

  11. {   

  12.   

  13. Button     button1,button2;   

  14. EditText   text1,text2;   

  15.   

  16.     @Override  

  17.   

  18.     public void onCreate(Bundle icicle)   

  19.     {   

  20.         super.onCreate(icicle);   

  21.         setContentView(R.layout.main);   

  22.     text1=  (EditText) findViewById(R.id.text1);   

  23.     button1 = (Button) findViewById(R.id.button1);   

  24.   

  25.     text2=  (EditText) findViewById(R.id.text2);   

  26.     button2 = (Button) findViewById(R.id.button2);   

  27.     button1.setOnClickListener(new clicker());   

  28.     button2.setOnClickListener(new clicker());   

  29.    }   

  30.   

  31.  //———————————–   

  32.   

  33.  class  clicker implements Button.OnClickListener   

  34.   {                  

  35.   public void onClick(View v)   

  36.      {   

  37.      if(v==button1){text1.setText(“welcome”); }   

  38.      if(v==button2){text2.setText(“hello”);   }        

  39.      }   

  40.   

  41.   }   

  42.   

  43. }  

The Android documentation and sample programs use anonymous inner class. I think it is quite unnecessary and is very tedious to follow. Instead, I have used user-defined ‘clicker’. This makes the code cleaner and more readable. This is just like any Swing program. In Android Terminology, an Activity is like a frame in swing (a screen). Just like ActionListener, here also we have, OnClickListener. I am not going into detailed theory now. I just  want to show how to develop and run a program first. Theory will follow later.


We have to copy this file(demo.java) to D:\android\tools\demo\src\mypack\mydemos


Go to d:\android\tools\demo

Give path= c:\winNT\system32;c:\jdk1.5\bin;e:\ant1.6\bin

(carefully note that this will not work with jdk1.4.2. It requires jdk1.5).


Secondly, how about the reference to Ant? Ant is a famous build tool from Apache Software foundation. Android requires the latest version of Ant for Windows(ie) Ant1.6. Do I have to know how to write the Ant’s build.xml file? NO. It is automatically created by the command.


So, I downloaded ant1.6 from the Apache website. It is a compact zip file. I have unzipped it and placed it as E:\ant1.6). Now use the command ‘ant’


d:\android\tools\demo>ant

We will get a series of messages. If we had done the previous steps correctly, we will get the message ‘BUILD SUCCESSFUL”.  Otherwise, we will get error messages, with line numbers where the errors occurred. We can correct them and build again.


The build process would have created a zip file named ‘demo.apk’ in demo\bin folder. All that remains now is to run the program in the emulator. As you remember, we have already started the emulator and it is running.


Now copy d:\android\tools\demo\bin\demo.apk  to d:\android\tools. After copying, give the command as:


…\tools>adb   install    demo.apk

After giving this command. go to the emulator window. You will find a checkpattern displayed for a while. Then an additional button appears in the screen with caption ‘demo’. Our program has been installed. We can test it by clicking on this ‘demo’button.


 



You can execute the program ‘demo’ now. Two textboxes and two buttons will appear. Click on button1. ‘welcome’ will appear in text1. Click on button2.’how are you?’ will appear in text2. The result is shown  below.



That completes our first  demo in  android.


We will be following exactly same procedure for all our demos. We will hereafter, see xml file and java files only, for the various demos. After a few more demos, it will be enough if I give the imports, declaration, definition and event handler.


The Android SDK comes with a number of sample applications. Within the APIDemos folder, we have a folder named ‘Views‘. I read it as ‘GUI’. It deals with layouts and controls and animations etc. There are a lot of demos. It may be confusing at first. Though, we may like to modify and simplify the code later, it is instructive to try each one of the sample programs by clicking on ‘apidemos’ button in the emulator screen and getting familiarity . I will list and give a brief comment on these, later.


 


Demo 2 – Spinner


As usual, the standard widgets are label(textview), textbox(edittext), combo(spinner), check, radio, ticker etc. I will now give a  demo for spinner. I have provided a spinner, button and a text to display the selected item in edittext.


We can design our layout as before using DroidDraw and get the following main.xml.


(obtained by using DroidDraw).





  1. <?xml version=“1.0” encoding=“utf-8”?>  

  2. <AbsoluteLayout android:id=“@+id/widget0”    

  3.     android:layout_width=“fill_parent”    

  4.      android:layout_height=“fill_parent”    

  5.       xmlns:android=“http://schemas.android.com/ apk/res/android”>                                               

  6. <Spinner  android:id=“@+id/spinner1” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:layout_x=“70px” android:layout_y=“42px”>                                               

  7. </Spinner>  

  8. <Button android:id=“@+id/button1” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:text=“confirm” android:layout_x=“70px” android:layout_y=“112px”>                                           </Button>                                      

  9. <EditText android:id=“@+id/text1” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:text=“EditText” android:textSize=“18sp” android:layout_x=“70px” android:layout_y=“182px”>  

  10. </EditText>  

  11. </AbsoluteLayout>  

The corresponding java source file is given below.





  1. package  mypack.mydemos;         

  2.   

  3. import android.app.Activity;                     

  4. import android.os.Bundle;                        

  5. import android.widget.*;      

  6. import android.view.View;   

  7.   

  8. public class  demo extends Activity              

  9. {                                                       

  10.         Spinner   spinner1;  

  11.         Button    button1;             

  12.         EditText   text1;    

  13.   

  14.       @Override                                                  

  15.       protected void onCreate(Bundle icicle)     

  16.   

  17.       {         

  18.                 super.onCreate(icicle);                             

  19.                 setTheme(android.R.style.Theme_Dark);  

  20.                 setContentView(R.layout.main);     

  21.     spinner1 = (Spinner)    

  22.     findViewById  (R.id.spinner1);     

  23.     button1    = (Button);  

  24.     findViewById (R.id.button1);                                                 

  25.     text1      = (EditText)    

  26.     findViewById  (R.id.text1);          

  27.     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, array);           

  28.     adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_ item);                      

  29.     spinner1.setAdapter(adapter);           

  30.     button1.setOnClickListener(  new clicker());      

  31.    }            

  32.   

  33.          private static final String[] array = {        “sunday”“monday”“tuesday”“wednesday”,  

  34.                          “thursday”“friday”“saturday” };     

  35.   

  36. class  clicker implements  Button.OnClickListener   

  37.   

  38. {   

  39.     public   void  onClick(View   v)  

  40.               {           

  41.            String       s = (String) spinner1.getSelectedItem();   

  42.              text1.setText(s);                                  

  43.     }                                            

  44.   

  45. }      

  46.   

  47.   

  48. }  

As before place demo.java in d:\android\tools\demo\src\mypack\mydemos. Place main.xml in d:\android\tools\demo\res\layout


Build using ant. Deploy demo.apk to the emulator exactly as in previous demo. The original demo gets overwritten. But, our work folder , where we have our xml and java files is d:\android\mydemos\ex1.They  are intact. So, no problem..The current java and xml files are in d:\android\mydemos\ex2.


When we click on the spinner, we get the items displayed as drop-down. We select an item and confirm. The selected item appears in text1. I am not going to explain the code. It is simple enough, if we remember our core java.



Demo 3 – Ticker


The third demo is a ‘ticker’ having a textbox for entering the ticker’s text, a ticker(timer) , two labels(editview) one for status and the other for diplaying the sliding message.





  1. <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android   

  2.    android:layout_width=“fill_parent”       

  3.    android:layout_height=“fill_parent”       

  4.    android:orientation=“vertical”>                                                                              

  5. <EditText android:id=“@+id/text1”           

  6.    android:layout_width=“fill_parent”           

  7.    android:layout_height=“wrap_content” />                                                                             

  8. <Ticker android:id=“@+id/ticker1”           

  9. android:layout_width=“fill_parent”           

  10. android:layout_height=“wrap_content”    

  11. android:layout_marginTop=“20dip” />                                                                      

  12. <TextView android:id=“@+id/label1”               

  13.   android:layout_width=“wrap_content”               

  14.   android:layout_height=“fill_parent” />                                                                       

  15.  </Ticker>  

  16. <TextView android:id=“@+id/label2”           

  17.   android:layout_width=“fill_parent”           

  18.   android:layout_height=“wrap_content”           

  19.    android:layout_marginTop=“20dip”  />                                                             

  20. </LinearLayout>  

 LinearLayout with vertical orientation is like FlowLayout but in a vertical direction.






  1. package mypack.mydemos;   

  2.   

  3. import android.app.Activity;   

  4. import android.os.Handler;   

  5. import android.os.Bundle;   

  6. import android.view.View;   

  7. import android.view.View.OnClickListener;   

  8. import android.widget.*;   

  9. import java.util.Map;   

  10.   

  11. public class demo extends Activity   

  12.   

  13. implements Ticker.TickerListener {   

  14.     Ticker ticker1;   

  15.     TextView label1, label2;   

  16.     EditText text1;   

  17.   

  18.     @Override  

  19.     protected void onCreate(Bundle icicle) {   

  20.         super.onCreate(icicle);   

  21.         setContentView(R.layout.main);   

  22.         ticker1 = (Ticker) findViewById(R.id.ticker1);   

  23.         label1 = (TextView) findViewById(R.id.label1);   

  24.         label2 = (TextView) findViewById(R.id.label2);   

  25.         text1 = (EditText) findViewById(R.id.text1);   

  26.         ticker1.setTickerListener(this);   

  27.         text1.setOnClickListener(new clicker());   

  28.     }   

  29.   

  30.     class clicker implements EditText.OnClickListener {   

  31.         public void onClick(View v) {   

  32.   

  33.             label1.setText(text1.getText());   

  34.             ticker1.startTicker();   

  35.             label2.setText(“Ticking…”);   

  36.         }   

  37.     }   

  38.   

  39.     public void onTickerFinished(Ticker view) {   

  40.         label2.setText(“Done!”);   

  41.     }   

  42.   

  43. }  

 


Demo 4 – Checkbox 


Copy this to tools\demo\res\layout\


 





  1. <?xml version=“1.0” encoding=“utf-8”?>  

  2. <AbsoluteLayout android:id=“@+id/widget1”  

  3.     android:layout_width=“fill_parent” android:layout_height=“fill_parent”  

  4.     xmlns:android=“http://schemas.android.com/ apk/res/android”>  

  5.     <CheckBox android:id=“@+id/check1”  

  6.         android:layout_width=“wrap_content”  

  7.         android:layout_height=“wrap_content” android:text=“java”  

  8.         android:layout_x=“50px” android:layout_y=“22px”>  

  9.     </CheckBox>  

  10.   

  11.     <CheckBox android:id=“@+id/check2”  

  12.         android:layout_width=“wrap_content”  

  13.         android:layout_height=“wrap_content” android:text=“C#”  

  14.         android:layout_x=“50px” android:layout_y=“72px”>  

  15.     </CheckBox>  

  16.   

  17.     <Button android:id=“@+id/button1”  

  18.         android:layout_width=“wrap_content”  

  19.         android:layout_height=“wrap_content” android:text=“Confirm”  

  20.         android:layout_x=“60px” android:layout_y=“122px”>  

  21.     </Button>  

  22.   

  23.     <EditText android:id=“@+id/text1”  

  24.         android:layout_width=“wrap_content”  

  25.         android:layout_height=“wrap_content” android:text=“EditText”  

  26.         android:textSize=“18sp” android:layout_x=“60px”  

  27.         android:layout_y=“202px”>  

  28.     </EditText>  

  29. </AbsoluteLayout>  

 


To be copied to tools\demo\mypack\mydemos





  1. package mypack.mydemos;   

  2.   

  3. import android.app.Activity;   

  4. import android.os.Bundle;   

  5. import android.view.View;   

  6. import android.widget.*;   

  7.   

  8. public class demo extends Activity   

  9.   

  10. {   

  11.   

  12.     Button button1;   

  13.     CheckBox check1, check2;   

  14.     EditText text1;   

  15.   

  16.     @Override  

  17.     public void onCreate(Bundle icicle)   

  18.   

  19.     {   

  20.         super.onCreate(icicle);   

  21.         setContentView(R.layout.main);   

  22.         text1 = (EditText) this.findViewById(R.id.text1);   

  23.         check1 = (CheckBox) findViewById(R.id.check1);   

  24.         check2 = (CheckBox) findViewById(R.id.check2);   

  25.   

  26.         button1 = (Button) findViewById(R.id.button1);   

  27.         button1.setOnClickListener(new clicker());   

  28.   

  29.     }   

  30.   

  31.     class clicker implements Button.OnClickListener   

  32.   

  33.     {   

  34.         public void onClick(View v)   

  35.   

  36.         {   

  37.   

  38.             String r = “”;   

  39.             if (check1.isChecked())   

  40.             {   

  41.                 r = r + “java” + “\n”;   

  42.             }   

  43.             if (check2.isChecked())   

  44.             {   

  45.                 r = r + “c#”;   

  46.             }   

  47.             text1.setText(r);   

  48.         }   

  49.   

  50.     }   

  51.   

  52. }  

 


This is just the usual Java code and needs very little explanation. The only difference is the way , the controls are defined ( through res\layout\xml file).


 


Demo 5 – RadioButtons


The next standard control is the RadioButton, within a RadioGroup.


To be placed in tools\demo\res\layout





  1. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  

  2.     android:orientation=“vertical” android:layout_width=“fill_parent”  

  3.     android:layout_height=“wrap_content”>  

  4.     <RadioGroup android:id=“@+id/group1” android:layout_width=“fill_parent”  

  5.         android:layout_height=“wrap_content” android:orientation=“vertical”>  

  6.         <RadioButton android:id=“@+id/radio1” android:text=“madras”  

  7.             android:layout_width=“wrap_content” android:layout_height=“wrap_content” />  

  8.         <RadioButton android:id=“@+id/radio2” android:text=“bombay”  

  9.             android:layout_width=“wrap_content” android:layout_height=“wrap_content” />  

  10.     </RadioGroup>  

  11.     <Button android:id=“@+id/button1” android:layout_width=“wrap_content”  

  12.         android:layout_height=“wrap_content” android:text=“Button” />  

  13.     <TextView android:id=“@+id/label1” android:layout_width=“wrap_content”  

  14.         android:layout_height=“wrap_content” android:text=“where” />  

  15.     <EditText android:id=“@+id/text1” android:layout_width=“wrap_content”  

  16.         android:layout_height=“wrap_content” android:text=“” android:textSize=“18sp”  

  17.         android:layout_x=“70px” android:layout_y=“182px” />  

  18. </LinearLayout>  

The following Java code should be placed in tools\demo\src\mypack\mydemo





  1. package mypack.mydemos;   

  2.   

  3. import android.app.Activity;   

  4.   

  5. import android.os.Bundle;   

  6.   

  7. import android.view.View;   

  8.   

  9. import android.widget.*;   

  10.   

  11. public class demo extends Activity   

  12.   

  13. {   

  14.   

  15.     TextView label1;   

  16.   

  17.     RadioGroup group1;   

  18.   

  19.     RadioButton radio1, radio2;   

  20.   

  21.     Button button1;   

  22.   

  23.     EditText text1;   

  24.   

  25.     @Override  

  26.     protected void onCreate(Bundle icicle)   

  27.   

  28.     {   

  29.   

  30.         super.onCreate(icicle);   

  31.   

  32.         setContentView(R.layout.main);   

  33.   

  34.         group1 = (RadioGroup)   

  35.   

  36.         findViewById(R.id.group1);   

  37.   

  38.         radio1 = (RadioButton)   

  39.   

  40.         findViewById(R.id.radio1);   

  41.   

  42.         radio2 = (RadioButton)   

  43.   

  44.         findViewById(R.id.radio2);   

  45.   

  46.         button1 = (Button) findViewById(R.id.button1);   

  47.   

  48.         text1 = (EditText) findViewById(R.id.text1);   

  49.   

  50.         text1.setText(“radio”);   

  51.   

  52.         label1 = (TextView) findViewById(R.id.label1);   

  53.   

  54.         label1.setText(“where?”);   

  55.   

  56.         button1.setOnClickListener(new clicker());   

  57.   

  58.     }   

  59.   

  60.     // …inner class —follows ->   

  61.   

  62.     class clicker implements Button.OnClickListener   

  63.   

  64.     {   

  65.   

  66.         public void onClick(View v)   

  67.   

  68.         {   

  69.   

  70.             if (v == button1)   

  71.   

  72.             {   

  73.   

  74.                 if (radio1.isChecked())   

  75.   

  76.                 {   

  77.                     text1.setText(“madras”);   

  78.                 }   

  79.   

  80.                 if (radio2.isChecked())   

  81.   

  82.                 {   

  83.                     text1.setText(“bombay”);   

  84.                 }   

  85.   

  86.             }   

  87.   

  88.         }   

  89.   

  90.     }   

  91.   

  92.     // —-inner class ends here —   

  93.   

  94. }  

 


You would have observed that I am naming all my java files as ‘demo.java’. May be confusing at first but I am doing so with a purpose. First of all, the emulator screen gets cluttered with too many buttons if we go on adding my examples. What I have done is :


I have created a folder as d:\android\mydemos.


In mydemos folder, I have created subfolders such as (ex1,ex2 etc). But, within each folder, I have demo.java & main.xml.


This way, we can easily test each of our demos  by uniform procedure. In my system, I had the problem of insufficient memory. And, by the above step, I was able to test all my programs by the same name.


Here is an important tip however, if you choose to name the source files and xml files differently and want to reduce the clutter.


Demo 6 – Gallery 


Interestingly, there is a ready-made control in the toolbox, named ‘gallery’. Let us now learn to use this control, though the syntax is a bit difficult. This time, we will need demo.java, main.xml and also another folder in tools\demo\res\drawable. This special folder is to be created by us. You can read ‘img’ instead of ‘drawable’. So, we place all the image files to be displayed in the gallery, in this folder.


 


Let us as usual create the xml file by using DroidDraw as follows.


 





  1. <?xml version=“1.0” encoding=“utf-8”?>  

  2. <Gallery xmlns:android=“http://schemas.android.com/apk/res/android”  

  3.     android:id=“@+id/gallery” android:layout_width=“fill_parent”  

  4.     android:layout_height=“fill_parent” android:layout_alignParentBottom=“true”  

  5.     android:layout_alignParentLeft=“true” android:gravity=“center_vertical”  

  6.     android:spacing=“5” />  

 


The following class is to be placed in tools\demo\mypack\mydemos





  1. package mypack.mydemos;   

  2.   

  3. import android.app.Activity;   

  4. import android.content.Context;   

  5. import android.os.Bundle;   

  6. import android.view.View;   

  7. import android.view.ViewGroup;   

  8. import android.widget.*;   

  9. import android.widget.AdapterView.OnItemClickListener;   

  10.   

  11. public class example extends Activity   

  12.   

  13. {   

  14.   

  15.     @Override  

  16.     public void onCreate(Bundle icicle) {   

  17.   

  18.         super.onCreate(icicle);   

  19.         setContentView(R.layout.main);   

  20.         Gallery gallery = (Gallery)   

  21.         findViewById(R.id.gallery);   

  22.         gallery.setAdapter(new ImageAdapter(this));   

  23.         gallery.setOnItemClickListener(new OnItemClickListener()   

  24.         {   

  25.   

  26.             public void onItemClick(AdapterView parent,   

  27.             View v,   

  28.             int position,   

  29.             long id)   

  30.   

  31.             {   

  32.   

  33.                 Toast.makeText(example.this“” + position,   

  34.                 Toast.LENGTH_SHORT).show();   

  35.             }   

  36.   

  37.         });   

  38.   

  39.     }   

  40.   

  41.     public class ImageAdapter extends BaseAdapter   

  42.     {   

  43.   

  44.         public ImageAdapter(Context c)   

  45.         {   

  46.             mContext = c;   

  47.         }   

  48.   

  49.         public int getCount()   

  50.         {   

  51.             return mImageIds.length;   

  52.         }   

  53.   

  54.         public Object getItem(int position)   

  55.         {   

  56.             return position;   

  57.         }   

  58.   

  59.         public long getItemId(int position)   

  60.         {   

  61.             return position;   

  62.         }   

  63.   

  64.         public View getView(int position, View   

  65.         convertView, ViewGroup parent)   

  66.         {   

  67.             ImageView i = new ImageView(mContext);   

  68.             i.setImageResource(mImageIds[position]);   

  69.             i.setScaleType(ImageView.ScaleType.FIT_XY);   

  70.             i.setLayoutParams(new Gallery.LayoutParams(160200));   

  71.             return i;   

  72.         }   

  73.   

  74.         public float getAlpha(boolean focused, int offset)   

  75.         {   

  76.             return Math.max(01.0f – (0.2f * Math.abs(offset)));   

  77.         }   

  78.   

  79.         public float getScale(boolean focused, int offset)   

  80.         {   

  81.             return Math.max(01.0f – (0.2f *   

  82.             Math.abs(offset)));   

  83.         }   

  84.         private Context mContext;   

  85.         private Integer[] mImageIds = {   

  86.         R.drawable.cindy,   

  87.         R.drawable.clinton,   

  88.         R.drawable.ford,   

  89.         R.drawable.cybil,   

  90.         R.drawable.demi,   

  91.         R.drawable.colin,   

  92.         R.drawable.david,   

  93.         R.drawable.drew   

  94.         };   

  95.   

  96.     }   

  97.   

  98. }  

How to uninstall an application from the emulator?



  • Make sure your emulator is running
  • Open a dos box in the android/tools folder  d:\android\tools>adb shell 
  • You will get the shell prompt
     #cd /data/app
     #ls
     (It will list all the *.apk installed in your emulator)
    # rm  example.apk
    ( if you want to remove ‘example’)
    #exit
  • You will see the application getting removed from the emulator at the same moment

 


That completes the first part of my introductory tutorial on Android SDK.


 

Is Hibernate the best choice?


Is Hibernate the best choice? Or is the technical marketing of other ORM vendors lacking?


Recently Jonathan Lehr posed a question on his blog: “Is Hibernate the best choice?“, and this lead me to ask the same question.


Although, I tend to use Hibernate as my first choice, it would be nice to see some head to head comparisons of Hibernate vs. TopLink (pros and cons), Hibernate vs. OpenJPA, Hibernate vs. Cayenne, etc. Searching around finds that many of the comparison are pretty old and not very detailed or compelling.


Having used other ORM frameworks, I found that when something goes wrong with Hibernate, you can usually google and find an answer, and there are many books on Hibernate. In my experience, the other frameworks seemed to be a less well-worn path and it is harder to find answers to even common problems. This is not to say that Hibernate is better, but that it is a lot more popular. In the end, I use Hibernate because my clients use it, if my clients switched to TopLink or OpenJPA, then I would use them as well.

So this begs the question, if Hibernate works for you, you just might have something else to do, like implementing a client solution that makes your client money, than to try several other ORM frameworks. How much time should someone spend learning a new ORM framework (new to them anyway)?


Don’t get this wrong, trying out new ORM frameworks is fine. If there is a large IT/developer organization, and you have a certain selection criteria like integrating with legacy databases, conformance to JPA specification, ability to hire new developers, easy of use, etc. then by all means having someone create a few prototypes and/or proofs of concepts and try out a few ORM frameworks is great. There is often good ROI in this type of testing. Perhaps share your findings with the rest of us.


However, it seems if you are a vendor of a JPA solution, you could start by pointing out how your product differs from Hibernate. Like it or not, Hibernate dominates the mind-share of developers. If you can’t prove your ORM frameworks has compelling reasons for switching, why should developers spend their time evaluating your product?


Now let me boil things down to brass tacks, it seems vendors of the ORMs should write white-papers, articles, blogs, and such to highlight the advantages of their ORM framework versus Hibernate. Logic dictates that if you have a product and there is a competing product that dominates the market that you might want to highlight what differentiates your product from the dominate one.


As a test, let’s go to different vendor sites and see if they have comparisons of their ORM framework vs. the 800 pound gorilla, Hibernate.


So first let’s go to Oracle TopLink website, you would expect since Hibernate has such a huge adoption rate in the industry that Oracle would want to point out why TopLink is better like a nice white-paper perhaps featured prominently on their TopLink site (see graph).


TopLink versus Hibernate


After hunting around a bit this entry appeared in the TopLink Essentials FAQ, Why should TopLink Essentials be used instead of JBoss(TM) Hibernate?


The two main points that seemed intriguing were as follows:


“Customers with any degree of complexity in the domain model or relational schemas, most notably where changing the schema is not an option, will benefit from the flexibility and proven nature of TopLink.”


NOTE: At times mapping Hibernate to legacy systems can be challenging. How is TopLink better at this? Are there articles or white-papers, etc. that attempt to prove that TopLink is better at legacy integration? (I find that many developers are not aware of all of the features that Hibernate provides for legacy mapping.)



“As the reference implementation of JPA TopLink offers the first certified implementation of this new standard. as well as providing some useful value-add functionality. Going forward this open source project will continue to innovate based on contributions from Oracle, Sun, and others.”


NOTE: This is compelling to me since I now use the JPA interface to Hibernate whenever I can.


Now I did not find the arguments in the FAQ particularly compelling or at all detailed. Sadly, you can find more compelling arguments in some of the TopLink public forums and random blogs. However, none so compelling that I feel the sudden need to switch.


Now on to the BEA site to look at dear KODO. I have always heard good things about KODO. Sadly, I found the BEA KODO site to be very out of date. It mentions a 2005 award for KODO as the lead news item. It also mentions that OpenJPA is in incubation, it has been out for a while. Even the FAQ, which did mention Hibernate, merely mentions that Hibernate is not EJB3 (seems it should say Hibernate is not JPA). This site really seems out of date and like the TopLink site mosty ignores the elephant in the room (see graph).


KODO vs. Hibernate


Well, let’s look at the Apache OpenJPA site, as KODO’s DNA may live at Apache long after Oracle decides on a single JPA solutions and likely leaves KODO to rot on the vine. Searching through the main site, FAQ, OpenJPA documentation, etc., I find no mention of Hibernate. Now this is an open source project so one would likely expect to see no marketing angle per se. But, you might expect that a project recognize that many would not be able to use this project without first justifying their pick against picking Hibernate (OpenJPA barely appears at all on job graphs). How many IT/development managers will feel comfortable with this choice without some explanation?


Now on to the next ORM framework site, Cayenne. No mention of Hibernate vs. Cayenne (but I know I have read articles on this). Seems like there might be some compelling ease-of-use arguments for Cayenne vs. Hibernate but they choose not to compare them. (Cayenne barely appears at all on job graphs)


Now back to Jonathan Lehr blog, Jonathan states that he feels TopLink and Cayenne are better choices than Hibernate and cites his reasons for these choices. There is a long discussion on the pros and cons of each in the comment section. I’d love to see more discussion, and I’d love to see some viable alternatives to Hibernate, but feel that no vendor or open source project does a real good job of pointing out the differences and possible limitations of Hibernate. If the vendors and project owners choose not to make their case, it makes it very difficult for the rank and file developers to make their case.


Perhaps one reason Hibernate is so dominate is because competing projects are so bad at technical marketing. Not one project I looked at mentions Hibernate on their front page. I could not find a decent comparison of features (to Hibernate’s) on any of the ORM sites.


Has anyone done a comparison of Hibernate and OpenJPA, TopLink Essentials, Cayenne that compares ease-of-use, caching, tool support, legacy integration, etc.? Perhaps such an internal report was used to decide which ORM tool to pick. If so, what were the results?


If you use TopLink, OpenJPA, Cayenne instead of Hibernate, why?


Were you hoping that JPA would level the playing field and there would be more competition?

Tomcat Today, GlassFish Tomorrow?

While there are indeed several advantages to using GlassFish vs. Tomcat, it’s probably useful to know that Sun is the original creator of Tomcat and that any application running today on Tomcat should run just fine (no modification whatsoever) on GlassFish.

Grizzly


Historically, if you wanted to get good HTTP performance from Tomcat you really needed to have a the Apache web server to sit in front of Tomcat which involved more setting up and extra administrative work. Since GlassFish v1 (May 2006), Grizzly is the HTTP frontend of the application server. It’s a 100% Java nio framework that provides the same performance as Apache only it’s written in Java and integrated straight into the application server. While using Apache or Sun Web Server in front of GlassFish is quite possible, it’s certainly no longer needed for performance reasons. Grizzly is also used for other protocols such as IIOP and now SIP (project Sailfin). Finally, Grizzly is the key technology for implementing Comet (aka Reverse Ajax, aka Ajax Push) which enables so very interesting push scenarios (from server to clients).


Full Java EE 5 support


Support for Java EE 5 (and soon Java EE 6) has always been a key priority for the GlassFish project. It delivered its first Java EE 5- certified implementation more than two years ago. This allowed developers to enjoy the much simplified EJB 3.0 specification, JAX-WS, and more goodness early on but it also provided dependency injection in the web tier (in servlet or JSF managed beans). Tomcat is not a full blown application server so while it may be enough for some developments, many companies find themselves maintaining a stack of frameworks and libraries on top of Tomcat when a GlassFish provides a JPA persistence engine (Toplink), a full web services stack (Metro), an application model (EJB3), and more, all out of the box. Java EE 6 profiles should help improve that situation for the industry as a whole.


Admin Tools


Administration and monitoring tools is what GlassFish users coming from Tomcat get as an immediate benefit. From web tools to command- line tools, GlassFish has an extensive set of features ranging from application (un)deployment, to JNDI resource creation, to all sorts of configuration details. All is JMX-based, exposed using MBeans (called AMX) and usable from JMX tools such as JConsole or the new VisualVM (specific plugin for GlassFish there). GlassFish also provides a fully- integrated monitoring feature called Call-Flow which reveals very accurately where time is being spent in the application before a response is sent. GlassFish also comes with a self-monitoring framework capable of implementing administrative rules such as the addition of a new node to a cluster if the average response time goes beyond a certain threshold.



Documentation


Technical information for GlassFish comes in various forms complementing one another quite well. The official documentation is extensive and complete (20+ books, from Developer’s Guide to Deployment Planning Guide). There’s also the Java EE tutorial, Enterprise Tech Tips, GlassFish user FAQs, blogs from engineers, forums and mailing lists.


Clustering


Full clustering is built right into GlassFish with no need to move to some other codebase or for-pay version of the product. In fact, you can even upgrade from a “developer” profile to a “cluster” profile. Clustering in GlassFish means the grouping technology (heartbeats, centralized admin), the load-balancing, but also the stateful data in- memory replication. Project Shoal is the GlassFish sub-project that does the heavy-lifting for most of these features. It uses JXTA under the covers which has the nice side-effect or requiring little to no configuration. GlassFish clustering make no assumption about the load- balancing technology used – it provides Web Server plugins but also works with hardware load-balancers. Such load-balancers do not need to know where the replicas are. Finally, Sun also offers a 99.999% solution with an in-memory distributed database (HADB). It has greater performance degradation, but probably unmatched availability.



Performance


Sun has literally worked for years on the performance of GlassFish – Grizzly, EJB container, Servlet container, Web Services, OpenMQ implementation, etc… The best result of this has been the SPECjAppServer world record published late last year and putting GlassFish in first place ahead of Weblogic and WebSphere (Tomcat isn’t a full app server and thus isn’t listed there, while JBoss has never published results). This is the first time one could claim that you no longer need to choose between open source and performance, you can have both. Performance is a strong priority for Sun.


Support from Sun


GlassFish is free and open source (dual CDDL + GPLv2 license), but Sun also has a business strategy to monetize GlassFish thru services. One such service is the subscription that covers access to patches and interim releases, access to support and escalation of bugs as well as indemnification. Sun also recently announced the GlassFish and MySQL unlimited offering (see http://www.sun.com/aboutsun/pr/2008-06/sunflash.20080627.1.xml) .


Tooling


While the NetBeans/GlassFish integration is very good, there is clearly no “NetBeans prerequisite” to use GlassFish. In fact Sun is the main developer of an open source plugin for Eclipse WTP to use GlassFish v2 and even v3. Both NetBeans and Eclipse users can get the plugin right from the IDE (for Eclipse, it’s a WTP plugin for Eclipse 3.3 or 3.4). There is also support for GlassFish in IntelliJ and Oracle has announced support in JDeveloper.


 


Tomcat, GlassFish v3


GlassFish has made a lot of efforts to appeal to developers. Its a single, small download of about 60MB, has auto-deploy capabilities, starts pretty fast for an application server with GlassFish v2 (probably the best full-blown application server startup time). To be fair to Tomcat or Jetty, they are still perceived by many as lighter- weight and faster to start. GlassFish v3 is all about being modular (based on OSGi), extensible and very developer friendly. The recently released TP2 (Tech Preview 2) starts in less than a second, starts/ stops containers and resources as needed and provides support for scripting technologies such as Rails, Groovy, PHP and more. There is also an Embedded mode for GlassFish which enables developers to use GlassFish via an API for testing or embeddability purposes. GlassFish v3 is scheduled to be aligned with Java EE 6 and released mid-2009. In the mean time there will be regular refreshes.


Ten Amazing Java Applications

Java is such a great language and platform for any kind of application. It is open, fast, powerful, runs on any platform, and there are more jobs for Java than any other programming language. After reading more FUD and Java bashing from Ruby land I thought it would be fun to put together a list of truly amazing uses of Java that covers a wide spectrum.


 


10 – Sun SPOT


The Sun SPOT Device is a small, wireless, battery powered experimental platform. It is programmed almost entirely in Java to allow regular programmers to create projects that used to require specialized embedded system development skills. The hardware platform includes a range of built-in sensors as well as the ability to easily interface to external devices. The SPOT Development Kit contains two complete, free-range Sun SPOTs (with processor, radio, sensor board and battery) and one basestation Sun SPOT (with processor and radio). Also included are all the software development tools and cables required to start developing applications for your Sun SPOT.


 


 


9 – Project Looking Glass


Project Looking Glass is an open source development project based on and evolved from Sun Microsystems’ advanced technology project. It supports running unmodified existing applications in a 3D space, as well as APIs for 3D window manager and application development. At the moment, existing application integration is supported for Solaris x86 and Linux platforms. The library for 3D application development is available for Linux, Solaris and Windows.


 


 


8 – Flying Saucer & Mozilla Rhino


Flying Saucer is 100% Java XHTML+CSS renderer, including support for table pagination, margin boxes, running elements, named pages, and more. It is CSS 2.1 compliant (currently working on CSS 3 compliance), can be embedded into your Swing applications, and uses the open source LGPL license. This is a very impressive library! Equally impressive is Mozilla Rhino. Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users. Imagine combining Flying Saucer, Applets/JavaFX Script support, Rhino, and the hugely improved “Consumer JRE”!


 


 


7 – UltraMixer


UltraMixer is a DJ mixing software which enables you to mix digital music in various formats such as MP3, WMA, AAC, OGG, WAV or CDs in real time. All you need is a sound card. The DJ’s turntables are replaced by two digital SoundPlayers, the “vinyls” are available within seconds through the integrated FileArchive. There are three versions of UltraMixer available: the Free Edition and the Basic Edition for private users and the Professional Edition for high demands and commercial use. It can interface with a number of hardware controllers so you don’t have to use a mouse.


 


 


6 – Blu-ray BD-J


The Blu-ray Disc Association (BDA) selected Java technology to be used as the platform for their advanced interactive application specification. Java technology was selected because:



  • Java technology has proven to be a technically sound solution in the mobile domain and in interactive television (MHP/OCAP)
  • Java technology has proven cross-platform technology support in embedded devices
  • Java technology provides an open-ended platform for content development with secure network support

I have seen a live demo of BD-J at JavaOne and was very impressed. Blu-ray seems to be winning the battle. It might finally be time to pick up a Blu-ray player.


 


 


5 – JavaFX Script & JavaFX Mobile


JavaFX Script is a compiled declarative scripting language that will soon be built into Java that enables Java developers and graphics designers to create rich user interfaces comparable to Adobe Flash. Recently key-frame animation support was added. The graphical designer tool being developed will be an Adobe Illustrator plugin. Rich Internet Applications built using JavaFX Script will run in the browser as an applet. An effort of cosmic proportions has been done to the Java Runtime Environment to improve startup time and responsiveness of applets.


 


JavaFX Mobile is a complete mobile operating and application environment built around Java and Linux open source technologies. JavaFX Mobile includes support for Java ME applications and other standard Java APIs to enable a broad range of new and existing Java applications. I think JavaFX Mobile brings a nearly complete Java SE environment to mobile devices (minus some things such as Corba, JMX, etc). Sun is a bit late in the game, but I think this will really pick up. I know I would prefer a full Java RIA over Adobe Flex.


 


4 – NASA World Wind


World Wind lets you zoom from satellite altitude into any place on Earth. Leveraging Landsat satellite imagery and Shuttle Radar Topography Mission data, World Wind lets you experience Earth terrain in visually rich 3D, just as if you were really there. It is very much like Google Earth, but written 100% in Java. There is an SDK for embedding it into your Java Swing applications.


 


 


3 – Team Jefferson’s Tommy Junior bot


Tommy Jr. is based on a Scion xB vehicle platform. The team’s secret weapon is the patent pending MAX software platform from Perrone Robotics. MAX represents the DNA and core robotics operating system that enables the rapid drop-in of commercially available and affordable sensors, hardware, and actuators. MAX is based 100% on Sun Microsystems’ Java technology. Tommy Junior’s micro-controllers and single low-cost standard car PC run the MAX robotics platform atop of standard, micro, and Java Real Time System (Java RTS) profiles.


The team’s after-market drop-in approach enables any vehicle whatsoever to be made fully autonomous within a short period of time. Tommy Junior’s cost in parts has been a mere $50,000 which includes the automotive platform itself. After actuators and hardware were dropped in, Tommy Junior was up and running in just 24 hours with Tommy senior navigation and obstacle avoidance capabilities. While Tommy Junior and Tommy senior share the same MAX DNA, Tommy Junior has since surpassed his father’s wits with new rules of behavior rapidly evolved for city driving.


 


2 – ThinkFree


ThinkFree is the compatible alternative to Microsoft Office. It includes ThinkFree Write (word processing), ThinkFree Calc (spreadsheet), and ThinkFree Show (presentation) applications that let you create, edit, and update your documents. The ThinkFree interface is designed to look, feel, and behaves like Microsoft Office, eliminating the learning curve. Because ThinkFree application use the same formats as Word, Excel, and PowerPoint, you can rest assured that your documents will look the same in ThinkFree as they do in Microsoft Office-no matter what editing features you are using. It can also save as PDF.


 


ThinkFree is written in Java, so it runs on Windows, Mac and Linux. There is a free online edition with 1 GB of storage, collaboration tools, publishing to blogs, web pages or ThinkFree Docs. I think it loads using Java Web Start? You can also host it on your own server, or run it as a desktop application.


 


1 – JPC


JPC is a pure Java emulation of an x86 PC with fully virtual peripherals. It runs anywhere you have a JVM, whether x86, RISC, mobile phone, set-top box, possibly even your refrigerator! All this, with the bulletproof security and stability of Java technology.


 


JPC creates a virtual computer upon which you can install your favorite operating system in a safe, flexible and powerful way. It aims to give you complete control over your favorite PC software’s execution environment, whatever your real hardware or operating system, and JPC’s multi-layered security makes it the safest solution for running the most dangerous software in quarantine – ideal for archiving viruses, hosting honey pots, and protecting your machine from malicious or unstable software.


It was hard to choose only ten application when there are so many cool looking scientific applications, 3D games, IDEs, languages that run on the JVM, etc. It’s incredible what people are doing with Java these days.


Also, there has been talk about aging mission critical real-time control systems transitioning to Java Real Time System (RTS) such as Nuclear Power Plants, Aircraft Control, Submarine Control, Factory Automation, Airport Aviation Flight Control, Energy and Power Systems Supply, Telecommunication Satellite and so forth. I saw a demonstration of the world’s fastest moving robot arm being controlled by a Java RTS application at JavaOne 2007. Very cool stuff.

The Best Java Tools You Never Knew Existed


I was at an awesome presentation at JavaOne of the long tail of Java tools that not many people have come across, which I had to share. So, in no particular order, and with my own emotive comments:



  • Apache Abdera – work easily with Atom feeds. See also Rome.

  • Antlr – this parser generator can look daunting, but it’s pretty easy once you get your head around it. Can be used to parse things like complex URLs where regexps are not up to the job.

  • ApacheDS – Java LDAP and Kerberos server, very easy to embed and great for testing your directory code. Now under the Apache Directory project which has heaps of other good stuff.

  • ASM – small, efficient bytecode manipulation

  • CGLIB – built on ASM, it works at a higher level and makes the former look like Assembler by comparison. Only downside is that it’s not well documented

  • JEXL – easily embeddable expression language, compares with OGNL

  • DisplayTag – JSP taglib for table formatting and exporting

  • EHCache – easy in-memory caching for everyone. Used this, it’s awesome.

  • Janino – someone took the time to write an embeddable Java compiler! It lets you use Java like a scripting language, eg. allow your users to type Java expressions directly into your GUIs.

  • Jar Jar Links – allows you to overcome namespace/package clashes between different versions of libraries used by your product by repackaging them. Similar to the Minijar Maven plugin that approaches the problem slightly differently by removing unused classes. Can be used to resolve dependency issues (classpath hell).

  • jDBI – substitute for JDBC that doesn’t suck when used directly

  • Jetty – web server/servlet container. Lightweight, yet lightning fast. Great for embedding, drives Grails.

  • Joda Time – date time library that kicks butt over java.util.Calendar. Intuitive (January is month 1!), easy to use and complete – everything that the java.util classes aren’t. Can be used alongside Date and Calendar. Chances are that the JSR based on this will become a part of Java 7, but why wait when you can use it now!

  • JSON-lib – best Java JSON library out there. Has good documentation. See also Jaxen.

  • Commons Math – everything from linear algebra to statistics

  • Mock Javamail – mock test infrastructure for Javamail code. See also Dumpster, Smartster.

  • Not-Yet-Commons-SSL – Nice, easy to use Java wrapper over OpenSSL. Encryption for the masses!

  • Selenium – test your web app interaction! HTML/JS, browser-based test environment – JUnit starts playing with windows :).

  • Selenium IDE – the “IDE” part may be overstating things, but this Firefox plugin generates the basis of your test code for you. See also Canoo Webtest.

  • Selenium Maven plugin – self explanatory

  • Sitemesh – like Tiles, but non-intrusive and heaps better. It hasn’t been updated for ages because it Just Works.

  • Smack – Java Jabber client

  • XStream – objects -> XML -> objects translation. I can’t recommend this one enough, awesome one to have in the toolbox.

  • StringTemplate – like Velocity, but better.

  • Ivy – this Ant plugin means that dependency management is not just for Maven any more. I worked on a big project that used this and it worked a treat.

  • Subetha – a mailing list manager and embeddable mail server. See also James.

  • Scriptella – extract, transform and load (ETL) tool for Java.

Feel free to add any gems that you have come across in the comments!


Resin 3.2.1 破解文件 crack keygen

resin3.2.1 的破解文件,仅供学习所用,不得用于商业用途.

把附件里的文件覆盖${resin_home}\lib里的pro.jar 即可
没用用户的可以用test/test 下载
如果你的版本不是是resin3.2.1,如果覆盖不能用时,可以试一下,把附件里的pro.jar里的 \com\caucho\license 目录覆盖你的pro里相应目录

linux下使用nload查看网卡实时流量

linux下使用nload查看网卡实时流量


nload是一个网络流量统计工具,当前版本为0.7.2。
下载地址:http://sourceforge.net/project/showfiles.php?group_id=35865


使用yum 安装也可以。


yum install nload


使用源码方式安装到/usr/local/nload,将/usr/local/nload/bin目录加入/etc/profile。


重新登陆ssh后,直接输入nload即可查看网卡的当前流量情况。
nload eth0 — 查看名叫eth0网卡的流量


可查看当前、平均、最小、最大、总共等的流量情况,单位为bit,详细的使用说明请参见:
http://www.debuntu.org/2006/07/14/74-nload-a-network-traffic-analyser


resin-pro-3.1.8破解下载

resin-pro-3.1.8在11月18号已经正式发布,这次有点慢了,主要是不知道这个版本已经发布了,以后有新版本发布时,请及时通知作者( dingl.com (At) gmail.com )。

破解下载 :

Resin Change Log

我会及时破解Resin的最新版本!

resin-pro-3.1.8.zip
resin-pro-3.1.8.tar.gz

原文:http://www.dingl.com/blog/archives/49

Linux/Ubuntu tar命令详解使用格式和方法

格式: tar 选项 文件目录列表
功能: 对文件目录进行打包备份
选项:
-c 建立新的归档文件
-r 向归档文件末尾追加文件
-x 从归档文件中解出文件
-O 将文件解开到标准输出
-v 处理过程中输出相关信息
-f 对普通文件操作
-z 调用gzip来压缩归档文件,与-x联用时调用gzip完成解压缩
-Z 调用compress来压缩归档文件,与-x联用时调用compress完成解压缩



例如:


1.将当前目录下所有.txt文件打包并压缩归档到文件this.tar.gz,我们可以使用


tar czvf this.tar.gz ./*.txt


2.将当前目录下的this.tar.gz中的文件解压到当前目录我们可以使用


tar xzvf this.tar.gz ./