Monday, April 19, 2010

Flex 4, Spark Architecture Overview: Notes

Based on a great article by Deepa Subramaniam.

Intro
  • Every Spark component consists of the skin class (defined declaratively via an MXML file) and a component class (defined via ActionScript).
  • Previous Flex component architecture and component set was MX, aka as Halo.
  • Spark components extend the MX class mx.core.UIComponent, and so Spark containers can hold MX components and vice-versa, and Spark and MX components can live side-by-side. The same component lifecycle methods, properties, and events that existed for the MX components apply to Spark components.
Skinning

Three key elements— data, parts, and states—define the skinning contract upon which Spark is founded:
  • Every Spark component class:

    • defines the data the component expects, 
    • defines the constituent parts that make up the component (aka skin parts), and 
    • defines the states the component can enter and exit; responsible for all of the event handling needed to identify when a state change has occurred and ensures the component is put in the right state.
  • The corresponding skin class:

    • how that data is visually displayed, 
    • how the parts are laid out and visualized (it instantiates the parts), and 
    • what the component looks like as it enters and exits different states.
New Capabilities of Spark Architecture
  • Effects in Spark: faster and more capable; can be invoked directly within Spark skin classes through state-based transitions.
  • New layouts


    • APIs for robust 2D and 3D transformations,
    • the ability to easily implement custom layouts
    • assignable layout

    • FXG and MXML Graphics: graphics library that captures drawing primitives as simple MXML tags. FXG is a declarative XML syntax for defining vector graphics in applications built with Flex and can be created by Adobe Illustrator (or manually) and understood by other Adobe CS tools as well as by FlashPlayer (and probably created and read by Catalyst).
    What Next
    For more information, read references from the base article  by Deepa Subramaniam. For examples and details on skinning read article by Ryan Frishberg. For more information on FXG, read this Adobe well written documentation.

      Thursday, April 1, 2010

      JPA with Hibernate on Glassfish 3

      Intro
      This post is simply a summary of a simple proof of concept. It shows how to:
      • create a stateless EJB3 bean
      • persist an entity using JPA with Hibernate as a JPA provider
      • configure JPA to use a datastore defined on Glassfish (uses pre-installed java/__default datastore, which uses pre-installed Derby/JavaDB) 
      You can download the source code for this sample from here (EJB3_First_Project_with_Test.zip).
       

      Entity
      @Entity
      public class Book implements Serializable {
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private int id;
       private String title;
       private float price;
       
       public Book() {
          super();
       }
      ...
      }
      
      Here, I have annotated the property, rather than the getter (not shown for brevity), since it feels more intuitive to me. I don't know if there is any advantage/difference of one vs the other other than my personal preference. The "@GeneratedValue(...)" annotation for primary key in JPA entity definition is not optional, as I expected. Using just the "@Id" annotation results in the primary key being not set (set to 0).


      EJB Bean
      The interface:
      @Remote
      public interface BookManager {
       public abstract int addBook(Book book);
       public abstract Book find(int bookId);
      }
      

      And the bean implementation:
      @Stateless(name="BookManager", mappedName = "ejb/BookManagerJNDI")
      @TransactionAttribute(TransactionAttributeType.REQUIRED)
      public class BookManagerImpl implements BookManager {
      
       // Dependency injection of Entity Manager for
       // the given persistence unit
       @PersistenceContext(unitName="pu1") EntityManager em;
       
       public int addBook(Book book) {
      
        // Transitions new instances to managed. On the
        // next flush or commit, the newly persisted
        // instances will be inserted into the datastore.
        em.persist(book);
        
        return book.getId();
       }
       
       @Override
       public Book find(int bookId) {
        return em.find(Book.class, bookId);
       }
      }
      

      The annotation @Stateless with the mappedName make the bean to get registered with JNDI. The
      TransactionAttributeType.REQUIRED tells the container to wrap each method in the class with a transaction.
       
      JPA Setup
      The persistence.xml file (put it into META-INF folder under src folder so it will be deployed onto the server)
      <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
          <persistence-unit name="pu1">
           <!-- Persistence provider -->  
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <jta-data-source>jdbc/__default</jta-data-source>
      
              <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
         <property name="hibernate.hbm2ddl.auto" value="create" />
         <property name="hibernate.show_sql" value="true" />
              </properties>
          </persistence-unit>
      </persistence>
      

      The "hibernate." prefix in persistence.xml file is not optional when adding properties of the JPA provider (Hibernate in this case). They are ignored without it, without a warning.

      Glassfish Setup
      Nothing other than installing the Hibernate component using the Glassfish console.

      Unit Tests
      The unit test:
      try {   
         InitialContext ctx = new InitialContext();
         BookManager bean = (BookManager) ctx.lookup("ejb/BookManagerJNDI");
         Book book = new Book("Chocolate Rain", 25.10f);
         int bookId = bean.addBook(book );
         book = null;
         
         book = bean.find(bookId);
         Assert.assertEquals("Chocolate Rain", book.getTitle());
        } catch (NamingException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         Assert.fail("Failed. Exception thrown.");
        }
      

      A Few Notes
      • Can JPA be used to create and index? Yes and no. Not in general. But it provides a limited capability. To create a unique constrain on a table, use @UniqueConstraint(columnNames={"EMP_BDAY", "EMP_NAME"})
        • How to specify the character column type length? Use @Column(length=50).
        • What the client can understand about the remote exception, in case the EJB bean fails? The remote exception is wrapped in a EJBException and returned to the client. For example, if the password for the DB is incorrect, the org.hibernate.exception.GenericJDBCException will be returned with a message "Cannot open connection" (when Hibernate is used as JPA provider).
         Conclusion
        A few things to try in the next proof of concept:
        • test the rollback function, if second of two persistence operations failed when both are in the same method of the BookManager class.
        • do a parent/child relationship.
         

        Thursday, March 11, 2010

        Hibernate Session and Transaction Management

        It seems, there are several approaches to manage Hibernate sessions and transactions:
        • explicitly by the application
        • explicitly by the application with ThreadLocal pattern (example)
        • via Hibernate transaction demarcation with JTA
        • via Hibernate transaction demarcation with plain JDBC
        • using Spring Framework
        • using EJB / CMT (container-managed transactions)
        For a good explanation of all options, other than ThreadLocal, see Hibernate document. Note that EJB, as well as JTA, are available even outside the J2EE container as a module. Also, supposedly, the Spring Framework can be easily used just for the functionality you decide to use from it and it doesn't require the application to use all parts of this framework.

        Basic Approach: Managed by Application
        Here's a code sample from hibernate document:
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
        
            // Do some work
            session.load(...);
            session.persist(...);
        
            tx.commit(); // Flush happens automatically
        }
        catch (RuntimeException e) {
            tx.rollback();
            throw e; // or display error message
        }
        finally {
            session.close();
        }
        
        You choose the approach.

        Monday, March 8, 2010

        Android Testing - Tips

        • What is Android Context class? It's "an interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system."
        • The native Android OS support for testing is based on jUnit 3. Don't try to use jUnit 4. The results are not predictable. I had the first test run fine, but no more tests would finish.
        • Testing support:

          • Use ActivityInstrumentationTestCase2 for functional testing of a single Activity. The selected activity will be created and managed by the system as specified by the regular activity lifecycle. Tests can interact with the UI widgets to imitate user actions.
          • Use ActivityUnitTestCase to run unit tests of an isolated activity. Activity under test will not be subject to regular activity lifecycle.
        • If you see a problem of type error: device not found and shutdown the adb.exe process. It will restart automatically and try to reconnect to the device. Sometimes, starting the intended Instrumentation on emulator (an option in Dev Tools application) does it all for you.
        • If adb does not connect after restarting it (shows "DeviceMonitor]Connection attempts: 11..." and LogCat nic nie pokazuje), restart PC.

        Tuesday, March 2, 2010

        JSON RESTfull Service Using Jersey with Hibernate Persistence on Glassfish - Part 2

        This is continuation of my blog on this topic. I'm adding the solution to the questions/issues left out in that first blog as delineated in the last part of the blog. Actually, this effort wasn't successful. I wasn't able to make it work. Although made a good progress, I had to go back to the approach presented in my previous blog. This post is just to document what I was able to achieve.

        JTA
        Switch to use JTA, instead of native JDBC transactions. All new application servers support JTA natively. With JTA, the session is bound to the transaction. If you call sessionFactory.getCurrentSession(), anytime between userTransaction.begin() and userTransaction.commit(), a session bound to this transaction is returned. User transaction is usually obtained via JNDI. So, an example of code:
        UserTransaction tx = (UserTransaction)new InitialContext()
         .lookup("java:comp/UserTransaction");
        
        SessionFactory factory = HibernateUtil.getSessionFactory();
        PersonDao dao = new PersonDao(factory);
        
        try{
         tx.begin();
         
         dao.saveOrUpdate(person);
         
            tx.commit();
        
        } catch( Exception ex) {
         tx.rollback();
        }
        
        while the only thing that the Dao needs to do is to request the session via: factory.getCurrentSession().

        The required Hibernate configuration file hibernate.cfg.xml:
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
        <hibernate-configuration>
            <session-factory name="hibernate/sessionFactory">
             <property name="transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>
             <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
                <property name="connection.datasource">jdbc/xaderby</property>
                <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
                <property name="current_session_context_class">jta</property>
                <property name="hbm2ddl.auto">create</property>
            
             <mapping resource="olcc/entity/Person.hbm.xml"/>
            </session-factory>
        </hibernate-configuration>
        
        where jdbc/xaderby is a data source defined on Glassfish, of type javax.sql.XADataSource.

        Configuration
        Glassfish 3
        Hibernate 3.5
        JDK 6 (Derby included)

        Result
        This configuration results in the following error message:

        FINEST: saving transient instance
        FINE: surrounding JTA transaction suspended [JavaEETransactionImpl: txId=1 nonXAResource=null jtsTx=null localTxStatus=0 syncs=[org.hibernate.transaction.CacheSynchronization, org.hibernate.context.JTASessionContext$CleanupSynch@1d069e4]]
        FINE: opening JDBC connection
        INFO: JTS5014: Recoverable JTS instance, serverId = [100]
        
        FINE: select next_hi from hibernate_unique_key for read only with rs
        FINE: update hibernate_unique_key set next_hi = ? where next_hi = ?
        FINE: closing JDBC connection (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)
        SEVERE: org.hibernate.HibernateException: unable to resume previously suspended transaction
            at org.hibernate.engine.transaction.Isolater$JtaDelegate.delegateWork(Isolater.java:179)
            at org.hibernate.engine.transaction.Isolater.doIsolatedWork(Isolater.java:64)
            at org.hibernate.engine.TransactionHelper.doWorkInNewTransaction(TransactionHelper.java:74)
            at org.hibernate.id.TableGenerator.generate(TableGenerator.java:118)
            at org.hibernate.id.TableHiLoGenerator.generate(TableHiLoGenerator.java:84)
            at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)
        When I tried using a plain javax.sql.DataSource instead of XADataSource, I was getting XAResource.start error.

        Remaining Questions:
        • findAllByProperty(), findByCriteria() and/or findByExample() methods. Commonly used. What is the right way to implement them?

        J2EE - Tips and Tricks

        • Sun/Oracle's J2EE 5 SDK is installed in small pieces. Unlike previous versions of J2EE, there is no j2ee.jar. And so, pieces of it are installed in glassfish\modules folder, as separate jars. For example, the JTA stuff is installed as jta.jar (the implmementation stuff, com.sun....* classes) and javax.transactions.jar, which holds the core of the JTA API.

        Saturday, February 27, 2010

        Android Development Tips and Issues

        General
        • After importing a project created by someone else, you may need to correct the Project Build Target via project Properties -> Android panel.
        UI
        • The attribute layou_height=fill_parent doesn't work as usually inside the ScrollView. Set the size explicitly, possibly using minHeight and MaxHeight.