Tuesday Jun 23, 2009

Buggy JPA support in Google App Engine

I wanted to develop application that allows me to track my running log on the web. Also, I wanted test NetBeans Google App Engine plugin that I was working in the last weeks. Since, I'm familiar with JPA I choose this datastore for my application and created the simple Activity entity class like this (app is hosted here):
    @Entity
public class Activity implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    private ActivityType type;
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar start;
    private int avgheartRate;
    private long duration;

    public Activity() {
        
    }
 
Then, I implemented facade class that access datastore and persist activity in database:
     public void createActivity(ActivityType type, Calendar start,
            int avgheartRate, long duration) {
        EntityManager em = PersistenceFactory.getFactory().createEntityManager();
        Activity activity = new Activity(type, start, avgheartRate, duration);
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(activity);
            tx.commit();
        } catch (Exception ex) {
            if(tx != null && tx.isActive())
            tx.rollback();
            Logger.getLogger(this.getClass().getCanonicalName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
        } finally {
             em.close();
        }
    }
 
Google App Engine has very nice support for unit testing hence I wrote simple test for above method and run tests. However, I got following exception:
 java.lang.UnsupportedOperationException
        at org.datanucleus.store.appengine.EntityUtils.getPropertyName(EntityUtils.java:60)
        at org.datanucleus.store.appengine.DatastoreFieldManager.getPropertyName(DatastoreFieldManager.java:872)
        at org.datanucleus.store.appengine.DatastoreFieldManager.storeObjectField(DatastoreFieldManager.java:757)
        at org.datanucleus.state.AbstractStateManager.providedObjectField(AbstractStateManager.java:1011)
        at org.mujbeh.model.Activity.jdoProvideField(Activity.java)
        at org.mujbeh.model.Activity.jdoProvideFields(Activity.java)
        at org.datanucleus.state.JDOStateManagerImpl.provideFields(JDOStateManagerImpl.java:2597)
        at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:180)
        at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3067)
        at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4395)
        at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2807)
        at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2747)
        at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2886)
        at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:348)
        at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:235)
        at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:104)
        at org.mujbeh.PersistenceFacadeImpl.createActivity(PersistenceFacadeImpl.java:37)
        at org.mujbeh.PersistenceFacadeImplTest.testCreateActivity(PersistenceFacadeImplTest.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:232)
        at junit.framework.TestSuite.run(TestSuite.java:227)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888)
 
I spent almost one hour on debugging and finding the issue in my code but without any success. Then, I found out that it's known issue that was reported in April 09. The issue and some workarounds that don't work for me are described here. There are many posts from users who encounter this issue in their applications. It seems as the stopper for Persistence in Google App Engine and totally blocks me to continue in my application. Above use cases is really crucial for every application that might be developed in Google App Engine. JPA support in Google App Engine SDK 1.2.1 is useless now.

Tuesday Jun 09, 2009

Google App Engine plugin in NetBeans

Me and several colleagues were thinking how to develop web applications for Google App Engine in NetBeans. We didn't find out any plugin that would support this functionality hence we decided to write support for this in NetBeans. The project is hosted here. Currently, we support following features:
  • Registering App Engine SDK in NetBeans as local J2EE server
  • The App Engine would be used as target server for JavaEE web projects
  • Generation of specific configuration file
  • Visual editor for appengin-web.xml
  • Debug web application on local App Engine server
  • Deployment to App Engine cloud
  • Editor hints
  • App Engine Samples
  • JPA support
  • File templates for cron, index files
  • Code completion in configuration files like cron, app-engine
Also, I recorded video how it's easy to develop Google App Engine application in NetBeans. You can see that Hello World takes just 1 minute. :-)

Wednesday Aug 30, 2006

Are JavaEE5 applications simple portable between particular servers?

I would like to verify whether Enterprise applications with JavaEE5 specifications are really portable between particular application servers. I believe that way could be more direct then for J2EE 1.4 when user should struggle with server specific deployment descriptors. I used simple enterprise applications that are included in NetBeans 5.5 (see File -> Samples -> Enterprise). These applications are developed and tested on Glassfish. Almost all advantages of the new specification are presented in these samples. I decided to migrate these samples on JBoss 4.0.4.
At the beginning, I realized that JBoss supports JavaEE5 specification only for EJB module not for Web and Ent application module. Therefore, no injection in these modules. Ok, I can use old approach with JNDI lookup. In the Glassfish you can use default JNDI name of interface that is fully qualified name of interface. This is very easy, isn't it? However, JBoss doesn't support this since it uses a little bit convention like: name of application/name of bean/interface(loca,remote). It means, all EJB clients should be changed.
I remeber, that mappedName attribute where JNDI name of bean could be used. I know that this is a product specific name but Glassfish use this as JNDI. However, this doesn't work on JBoss since they decided to drop this feature, see link. Also, one entity class uses two relations with EAGER fetch type since the related objects are used outside transaction. I realized that JBoss doean's support this configuration and workaround described here must be used.
I ended with many changes in my samples and tied application with specific server. The portability dropped away in my case. I see as the most important issue with different JNDI names in particular servers. Does JavaEE5 spec resolve this issue? Is there defined default JNDI names for stateless/stateful beans?

Monday Jun 05, 2006

Embedding JavaDB in your desktop application

JavaDB is very lightweight database that might be used for storing data in your desktop applications. I would like to show how to use embedded JavaDB in your applications. Let's to create desktop application that uses embedded database. In his mode the Derby database engine runs inside the same Java Virtual Machine (JVM) as the application. At first you need to download Derby database from here. Then, create new J2SE project and add derby.jar from Derby DB to project's classpath. We should load EmbeddedDriver, connect, add SQL code for inserting, selecting application data and we are done. See code snapshot:
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
    Connectionconn= 
     DriverManager.getConnection("jdbc:derby:myDB;create=true");
    conn.createStatement().execute("CREATE TABLE ...");
    ..... 
  
Now, run your applications and myDB directory with JavaDB files should be created in working directory. If you want to change a location when thies directory is created use derby.system.home Java system property. Persisting application data with embedded JavaDB is easy, isn't it?

JDBCRealm Tutorial

Edson Carlos Ericksson Richter just completed his tutorial about JDBC authentication in Glassfish. He wrote all steps that are needed for using this authentication in Glassfish b.48. Edson is the most productive participant in Netcat program. I believe he will publish many J2EE hints in his new blog.

Friday Jun 02, 2006

How to persist entity classes in XML file

I described how to persists your objects in database using Toplink in previous prost. However, sometimes you might want to save your objects in XML. It's very simple with NetBeans 5.5 since we included JAXB library in IDE. Let's to create application that stores information about orders in xml instead of in DB. This approach might be used when you want to send your objects via network. Just create new project in Netbeans 5.5 and select Libraries node in project tab, righ-click and choose Add Library item and select JAXB 2.0 in list, don't forget to click OK button.
Now, create Item class that holds info related to one item. This class might have name and amount fields and appropriate set/get methods for them. Since, I would like to have XML schema type with itemOrder name in generated schema then put following annotation above class definition:
    @XmlType(name="orderItem")
    public class Item implements Serializable {
    ........
  
Order class is similar as Item. Order has reference to items and also order number and due date. This class is top level class and should be annotated with the @XmlRootElement annotation. See code snapshot:
   @XmlRootElement()
    public class Order implements Serializable {    
    
    private String orderNumber;
    private Calendar dueDate;
    private Collection  items;
 
Working with these objects is very simple and intuitive. I will show only storing objects in XML but creation of objects from XML or update them is similar. See storing order in XML file:
   JAXBContext ctx = JAXBContext.newInstance(Order.class);
        Marshaller m = ctx.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);       
        File xml = new File("order.xml");
        
        Order order = new Order();
        order.setOrderNumber("FSX-2345-5454");
        order.addItem(new Item("book", 1));
        order.addItem(new Item("pen", 1));
        
        m.marshal(order, new FileOutputStream(xml));
 
When you run application, you can check order.xml. However, what's about creation schema from classes, it's easy as well. Only add following target in build.xml and rebuild project.
   <target name="-pre-compile">
        <taskdef name="schemagen"
        classname="com.sun.tools.jxc.SchemaGenTask"
        classpath="${javac.classpath}"/>
        <echo message= "Generating schemas..." />
        <mkdir dir="${build.dir}/schemas" />
        <schemagen destdir="${build.dir}/schemas" classpath="${javac.classpath}">
            <src path="${src.dir}" />
            <schema file="order.xsd"/>
        </schemagen>
    </target>
 
Working with JAXB is very easy in Netbeans 5.5. You don't need to download JWSDP pack since JAXB is bundled in IDE. In this post only java to XML binding is presented but you can simple create XML to Java as well. It means you will create objects from existing schema.

Friday May 26, 2006

Hibernate EntityManager library for Netbeans 5.5

Today, I wanted to use Hibernate EntityManager in one project. I downloaded Hibernate EntityManager from official pages. Then unziped the file and just used all jars in my project. However, I got NoClassDefFoundError when executed my project. I asked on Hibernate forum and got very quick response that Hibernate core is required for using Hibernate EntityManager. Thanks steckemetz for you hint.
Many jars are needed for running Hibernate on your project and it's not simple to find out all jars on Hibernate pages. Therefore, I decided to create Hibernate EntityManager library for NetBeans 5.5 that includes all required jars and JavaDoc as well. You can download NetBeans nbm here.
Install this nbm in NetBeans 5.5 and you can see new library in Tools - Library Manager. Now, let's use it. It's really simple. If you want to develop application that uses Hibernate as O/R framework you can follow same steps as for TopLink that is bundled with NetBeans by default. Create new application, you can choose J2SE project, web or EJb project and then create new persistence unit. In this wizard choose Hibernate as Persistence Library and generate persistence.xml.
You can see in file that correct Hibernate options and provider are used in this file. Next, you can use Hibernate provider in your code. This module provides code completion for Hibernate as weel, see screenshot:

Wednesday Apr 26, 2006

Developing Web services for Mustang in Netbeans

I read a very good blog about developing web services in Mustang a few weeks ago. However, described web service is very simple, you didn't need to generate WS artifacts for it. In real cases you might use Exceptions in you web method and then you should run wsgen before publishing web service. I would like to use how to develop this web service in last NetBeans 5.5 builds. For instance, my web service method throws some application exception like this:
     @WebMethod(name="getCountEmails")
     public int getTotalCount(@WebParam(name="email")String eMail) throws MailReportException {
            return reportServ.getMailBySender(eMail).size();
    }
  
Of course, project's target JVM should be jdk 1.6.0. Then, add JAX-WS 2.0 library on project's classpath and add these lines in project's build.xml script:
  <target name="-post-compile" depends="init">
        <echo message="Generate WS artifacts"/>
        <taskdef name="wsgen" classname="com.sun.tools.ws.ant.WsGen">
            <classpath path="${javac.classpath}"/>
        </taskdef>
        <wsgen
            debug="true"
            keep="true"
            destdir="build/classes"
            resourcedestdir="build/classes"
            sei="your.package.WSImplementation">
            <classpath>
                <pathelement path="${javac.classpath}"/>
                <pathelement location="${java.home}/../lib/tools.jar"/>
                <pathelement location="build/classes"/>
            </classpath>
        </wsgen>
    </target>
This task invokes wsgen and generate requested beans for exception. Now, you can publish web service:
  Endpoint.publish("http://localhost:8080/MyWebService", new MailReportWS());
run your project and test WSDL in browser.

Thursday Mar 30, 2006

Using TopLink persistence RI in Tomcat

New EJB 3.0 persistence can be used in web module as well but all samples show this new feature in JavaEE5 projects. I assume that many users want to use this cool feature in web projects that have J2EE 1.4 version. I would like to show in this post how to use persistence in web project that is deployed in Tomcat. Of course, on the Tomcat we can't use container managed entity manager. Therefore, the application managed EM is used in this sample. You can use JTA entity managers or resource-local entity manager. Since the Tomcat doesn't support JTA we can use only resource-local entity manager. Let's create new web project with J2EE 1.4 specification and target server Tomcat in NetBeans 5.5. Don't forget that project should have defined 1.5 jdk as platform and we should change source level to 1.5. Of course, the Tomcat server must run on jdk 1.5 as well. Add JavaEE5 library and JDBC driver on project's classpath.Then, add persistence unit and choose application managed entity manager and generate entity classes from database or create them from scratch. In this post is presented using entity manager in servlet but similar approch might be used in JSF managed bean or in class too. The Entity manager might be used as follows:
    EntityManagerFactory emF = Persistence.createEntityManagerFactory("Advertisement");
        EntityManager  em = emF.createEntityManager();
        try{
            em.getTransaction().begin();
            List advertisements =
                 em.createQuery("SELECT a FROM Advertisement a").getResultList();
            for (Advertisement elem : advertisements) {
                out.println(elem.getDescription() +  ", " + elem.getId() + "
"); } em.getTransaction().commit(); }catch(Exception ex) { em.getTransaction().rollback(); }finally { em.close(); }
Build and run project. This works on Tomcat but I encountered security issues on Sun Application server 8.2. The workaround is that you should grant permissions for web module in server.policy. Add following lines in this file:
    permission java.lang.RuntimePermission  "createClassLoader";
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
  
Now, you can use Toplink persistence in existing web projects instead of Hibernate :-).

Monday Mar 27, 2006

Using database in Enterprise application client module.

In my last post the new Netbeans project type was presented. Today, I would like to use this project and show how a database connection can be developed in Enterprise application client very simple. Let's start to create application that lists customers that are stored in database.
  • Create new Enterprise Application client project
  • Add new JFrame with name DisplayCustomernames in the project. In the form put JTable
  • Open project's properties panel and set this class as main class in the application
  • Open JFrame in source editor. Now, we should inject DataSource and creat table model
  • Injected property should be in Main class and should be static. We will use default JDBC resource in Glassfish that has a name jdbc/__deafult. Add these lines at beginning of the class:
            @Resource(name="jdbc/__default")
            private static DataSource ds;
         
  • Then, create Customer class that represents customer entity in database. This isn't needed in small application. Create new class Customer with id, name and email properties. Create set/get methods for these fields.
  • Create a model for JTable. Add new CustomerTblModel class that implements TableModel. In constructor add method that reads data from database:
          private void readData() {
            Connection conn = null;
            try{
            conn = ds.getConnection();
            PreparedStatement pStmt = 
                 conn.prepareStatement("SELECT CUSTOMER_ID, NAME, EMAIL FROM CUSTOMER");
            ResultSet rs = pStmt.executeQuery();
            while(rs.next()){
                custs.add(new Customer(rs.getInt(1), rs.getString(2), rs.getString(3)));
            }
            }catch(SQLException ex) {
                throw new RuntimeException(ex);
            }finally {
                if(conn != null) {
                    try {
                    conn.close();
                    } catch(SQLException ex) { }
                }
            }
        }
       
  • Don't forget set the table model in JFrame constructor after initComponents method:
          public DisplayCustomerNames() {
            initComponents();
            cstTableModel = new CustomerTableModel(ds);
            jTable1.setModel(cstTableModel);
        }
       
     
  • Run project.
Project sources are here.

Wednesday Mar 22, 2006

Enterprise application client project in NetBeans

My colleague Lukas Jungmann added the support for Enterprise application client in NetBeans 5.5. This feature is avalaible in the latest Netbeans 5.5 Q-build. He created this new project's type in his spare time. Thanks Lukas.
The project allows to create application client in EAR or as standalone module, user can run, debug the client inside the IDE.
An Enterprise application client has several adventages over J2SE client:
  • It has access to a component-local java:comp/env JNDI space
  • The client can handle remote access to J2EE connectors, meaning database connection pools, JMS, mail resources
  • The container can handle the server login process
  • Resources, EJB injection can be used.

Wednesday Mar 15, 2006

How to enable logging in file for Java Web Start applications

I'm working on application client that is launched via Web Start today. The client application was downloaded but there was some issue with execution. Therefore, I enabled Java Console in browser. The console is nice but it's closed suddenly when application can't start and execution is finished. This feature doesn't help me to find out the issue.
Then, I remembered for configuration of Logger for JRE. It's very simple configured via logging.properties file that is located in lib directory under your JRE home. By deafult, only ConsoleHandler is used and you can very simple add FileHandler. Add java.util.logging.FileHandler in handlers property. Then you can specify options for the FileHandler like file pattern, limit of write in bytes, number of files and formatter. The formattter is XML by deafult. However, this type isn't very well arranged for reading. I used SimpleFormatter for tracking exceptions in my client.
After these changes you can run application client again and open log file that is $HOME/javaX.log by default for FileHandler. I realized that a bug isn't in my application but in Glassfish itself. I reported it as the issue 406. I hope that I will win a iPod. :-)

Saturday Feb 25, 2006

Executing scheduled task by MBeans in Glassfish

In last blog the implementation of cron was described. I used lifecycle module and Timer bean in this approach. This solution was used since lifecycle listeners (similar as you know in web module) are missing for EJB module. It seems as lack of the specification. Therefore, server's vendors used some proprietary solutions like WebLogic defines some lifecycle methods in server specific deployment descriptors. Sankara suggested to use MBean with predefined Timer rules. Therefore, I decided to implement this task by MBean. We can use Netbeans plugin for JMX that is avalaible on update center and tutorial is here.
Now, let's create new J2SE project in Netbeans and create CronMB interface that tipically consists of named and typed attributes that can be read, written, and named typed operations that can be invoked, e.g. stop cron, change action, ... Then, create new class CronMBean class that implements this and javax.management.NotificationListener interfaces. Add business logic in handleNotification method. Now, build your module.
Logg in web admin console, select Custom MBeans node, click Deploy button and choose location of the jar with your cron MBean. Click Next and specify MBean class name. Now, we should create action that occurs based on timer action. Select Management Rules node and click Nwe button. Specify name and select timer as event type. In next panel specify additional info related to this timer and assign your MBean to the action.
I think that using custom MBean is better since this approach is more flexible then lifecycle module. Also, we can remote administrate this MBean.

Wednesday Feb 22, 2006

Faster deployment to Glassfish

I meet Jerome Dochez a two weeks ago and complained slow deployment to Glassfish. Our J2EE application that is developed in our team as referential application with EJB 3.0 has about ten entity and session beans. Deployment this application with one EJB and one web module took about 40 sec. I think that it's too much. Jerome suggested me to try to disable security manager in Glassfish. Therefore, I commented out following line with jvm-options in domain.xml file:
<jvm-options>-Djava.security.policy=${com.sun.aas.instanceRoot}/config/server.policy</jvm-options>
Then restarted server and deployed application. The deployment took 25 sec. It means deployment time was decreased by 37 percent. I think that doesn't make a sense use security manager on testing servers and I guess that many users don't need this feature. This security feature can be setup during server's installation. There might be a panel where user can select which type of server's configuration he wants: production or development and when he selects development mode the security manager can be disabled and logging can be switched to higher level, ...

Monday Feb 20, 2006

How to implement cron in Enterprise application

One my colleague asked me for implementing cron functionality in J2EE applicationthat is deployed in Sun application server. He needs to execute scheduled commandsin his EJB module. I suggested folowing solution that consists of Timer bean and lifecycle module that starts the timer when the server is started.
I know that better solution is used lifecycle module that is connected to EJB module only. For instance, where the module is deployed the lifecycle listener can invoke the bean. However, Sun Application server doesn't support this type lifecycle listener. The WebLogic server supports lifecycle listeneres on module application level, see here. Other solution is use servlet life cycle listener in web tier but this suggestion adds additional dependency for J2EE application. Since I didn't find better solution I used lifecycle module and Timer bean. Steps are below:
  • Create session bean that implements TimedObject interface. Then you should implement ejbTimout method that is invoked when the time expires.
  • Then create business method that creates interval timer:
         public void startTimer() {
            TimerService timerServ = context.getTimerService();
             // create interval timer
            Timer timer = timerServ.createTimer(new Date(), 5000, "Timer"); 
        }
      
  • Deploy EJB module and then we should create lifecycle listener that invokes startTimer method. Create new J2SE project and add appserv-rt.jar and j2ee.jar on project classpath
  • Create new class that implements com.sun.appserv.server.LifecycleListener interface.
  • Implements handleEvent method:
         public void handleEvent(LifecycleEvent lifecycleEvent) 
               throws ServerLifecycleException {
            // start timer when server is ready to service requests
            if(lifecycleEvent.getEventType() == LifecycleEvent.READY_EVENT){
                LifecycleEventContext lfcECtx = lifecycleEvent.getLifecycleEventContext();
                try {
                    lfcECtx.log("Try to lookup Timer's bean home: " + EJB_NAME);
                    InitialContext ctx = 
                              lifecycleEvent.getLifecycleEventContext().getInitialContext();
                    Object obj = ctx.lookup(EJB_NAME);
                    TimerSessionRemote timer =
                      ((TimerSessionRemoteHome)PortableRemoteObject.narrow(obj,
                                        TimerSessionRemoteHome.class)).create();
                    lfcECtx.log("Create Timer bean");
                    timer.createTimer();
  • Build project and copy jar file in lib directory that is in your domain. Don't forget to copy all libraries and EJB's stubs as well.
  • Go to web admin console and select node Applications - LifecycleModules. Click New button and create new Lifecycle module.
  • Restart application server and ejbTimeout method should be invoked every 5000 ms.
About

pblaha

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks