http://www.ibm.com/developerworks/cn/java/j-appfuse/
AppFuse is an open source project and application that uses open source tools built on the Java platform to help us develop WEB applications quickly and efficiently. I originally developed it to reduce the unnecessary time spent building new WEB applications for customers. From the core, AppFuse is a project skeleton, similar to what the IDE creates when you create a new Web project through the wizard. When we create a project using AppFuse, it prompts us to use the open source framework before creating the project. It uses ANT to drive testing, code generation, compilation, and deployment. It provides the directory and package structure, as well as the libraries needed to develop a Java-language-based WEB application.
Unlike most new project wizards, AppFuse-created projects contain many classes and files from the very beginning. These files are used to implement features, but they are also used as examples when you develop an application. By using AppFuse to start a new project, we can usually reduce development time by one to a week. We don't have to worry about how to configure the open source framework together because it's all done. Our projects are pre-configured to interact with the database, deployed to the application server, and authenticated to the user. We don't have to implement security features because it's already integrated.
When I first developed AppFuse, it only supported Struts and Hibernate. After several years of effort, I found a better web framework than Struts, so I added the options for these web frameworks. Now, AppFuse can support Hibernate or IBATIS as a persistence framework. For WEB frameworks, we can use JavaServer Faces (JSF), Spring MVC, Struts, Tapestry, or webwork.
AppFuse provides some of the features that many applications require, including:
- Certifications and authorizations
- User Management
- Remember Me (This will save your login information so that you don't have to log in every time)
- Password reminders
- Registration and Registration
- SSL Conversion
- E-Mail
- URL rewriting
- Skin
- Page Decorations
- templated layouts
- File Upload
This "out-of-the-box" feature is one of the differences between AppFuse and other crud generation frameworks (Crud taken from the English initials of creating, retrieving, updating, and deleting several operations), including Ruby on Rails, Trai LS and Grails. The frameworks mentioned above, as well as AppFuse, allow us to generate home/detail pages from database tables or existing model objects.
Figure 1 illustrates the conceptual design of a typical AppFuse application:
Figure 1. A typical AppFuse application
Listing 1 shows the command-line interaction we used when creating the Devworks project, and also gives the resulting results. This project uses WebWork as its own WEB framework (please refer to the links given in the resources section below).
Listing 1. Create a new project using AppFuse
Alotta:~/dev/appfuse mraible$ ant NewBuildfile:build.xmlclean: [echo] cleaning build and distribution Directoriesinit : NEW: [echo] [echo] +-------------------------------------------------------------+ [echo] | --Welcome to the AppFuse New application wizard! -- | [Echo] | | [Echo] | To create a new application, answer the following | [Echo] | Questions. | [echo] +-------------------------------------------------------------+ [input] what would-like to name your Applica tion [myapp]?devworks [input] what would you like to the name your database [mydb]?devworks [input] What the package name Wo Uld ORG.APPFUSE]?COM.IBM [input] What web framework would do I use [WEBWORK,TAPESTRY,SPRING,JSF , Struts]?webwork [echo] Creating new application named ' Devworks ' ... [Copy] Copying 359 Files To/users/mraible/work/devworks [Copy] Copying 181 files To/users/mraible/work/devworks/extras [copy] Copying 1 file to/users /mraible/work/devworks [Copy] Copying 1 file to/users/mraible/work/devworksinstall: [echo] Copying webwork JARs t O.. /.. /lib [Copy] Copying 6 files To/users/mraible/work/devworks/lib [echo] Adding webwork entries to: /.. /lib.properties [echo] Adding webwork classpath entries [echo] removing struts-specific JARs [delete] Deleting D irectory/users/mraible/work/devworks/lib/struts-1.2.9 [delete] Deleting directory/users/mraible/work/devworks/lib /strutstest-2.1.3 [echo] Deleting struts_form.xdt for XDoclet [delete] Deleting Directory/users/mraible/work/devwor Ks/metadata/templates [echo] Deleting Struts merge-files in Metadata/web [delete] Deleting 7 files From/users/mraib Le/work/devworks/metadata/web [echo] Deleting unused Tag Libraries and Utilities [delete] Deleting 2 files From/use rs/mraible/work/devworks/src/web/oRg/appfuse/webapp [echo] modifying Appgen for webwork [copy] Copying files to/users/mraible/work/devworks/extr As/appgen [Echo] replacing source and test files [delete] Deleting directory/users/mraible/work/devworks/src/web/or g/appfuse/webapp/form [Delete] Deleting directory/users/mraible/work/devworks/src/web/org/appfuse/webapp/action [C Opy] Copying files to/users/mraible/work/devworks/src [delete] Deleting directory/users/mraible/work/devworks/test /web/org/appfuse/webapp/form [delete] Deleting directory/users/mraible/work/devworks/test/web/org/appfuse/webapp/ Action [Copy] Copying 5 files To/users/mraible/work/devworks/test [echo] Replacing Web files (images, scripts, JS Ps, etc.) [Delete] Deleting 1 files from/users/mraible/work/devworks/web/scripts [copy] Copying files To/users/mraible/work/devworks /web [Delete] Deleting:/users/mraible/work/devworks/web/web-inf/validator-rules-custom.xml [echo] modifying Eclipse . classpath file [echo] refactoring build.xml [echo]----------------------------------------------[echo] Note:it s REC ommended you delete extras/webwork as you shouldn ' t need it anymore. [Echo]----------------------------------------------[echo] repackaging info written to Rename.log [Echo] [E Cho] +-------------------------------------------------------------+ [echo] | --Application created successfully! -- | [Echo] | | [Echo] | Now you should is able to CD to your application and run: | [Echo] | > Ant Setup Test-all | [echo] +-------------------------------------------------------------+build successfultotal time:15 seconds
Why use WebWork?
The struts community has recently embraced WebWork enthusiastically, a combination that has resulted in a very good new WEB framework for the Java platform: Struts 2. Of course, Spring MVC is a very good request-based framework, but it can't support JSF like Struts 2. Content-based frameworks (such as JSF and Tapestry) are good, but I find webwork more intuitive and easier to use (see Resources for more information about Structs 2 and JSF).
After creating a new project, we get a directory structure similar to the one shown in Figure 2. The Eclipse and Intellij idea project files are created as part of this process.
Figure 2. The directory structure of the project
This directory structure is very similar to the directory structure recommended by Sun for Java 2 Platform Enterprise Edition (EE) Web applications. In the 2.0 version of AppFuse, this structure changes to the standard directory structure for Apache Maven projects (see Resources for links to the contents of these two directories). AppFuse also migrates from Ant to Maven 2 to get the ability to download and support for building IDE project files. The current ANT-based system requires the submitter to maintain the project file, and Maven 2 can generate the idea, Eclipse, and NetBeans project files by simply using the project's Pom.xml file. (This file is located in the root directory of your project and is the main component needed to build your application using Maven.) It is very similar to the Build.xml file used by Ant. )
Now that we have a little idea of what AppFuse is, in the remainder of this article, we'll cover 7 points for using AppFuse. Even if you choose not to use AppFuse to start your own project, you will see that AppFuse can provide you with a lot of boilerplate code that can be used in a Java-based WEB application. Because it is based on the Apache license, you are welcome to reuse the code in your own application.
Reason 1: Test
Testing is a link that is rarely given enough trust in a software development project. Note I'm not saying that there's not enough trust in some of the publications in software development! Many articles and case studies have given a test-first development approach and adequate test coverage to improve the quality of the software. However, testing is often seen as something that will only prolong project development time. In fact, if we use test-first methods to write the test cases before writing the code, I believe we can see that this actually accelerates the development speed. In addition, test prioritization can make maintenance and reuse easier. If we do not write code to test our own code, then we need to test the application manually-which is usually inefficient. Automation is the key.
When we first started using AppFuse, we might need to read the Quick Start Guide and tutorials available on this project Web site (see Resources for a link). These tutorials are written so that you can write test cases first, and they are not compiled until the interface and/or implementation is written. If you're like me, you've written your test cases before you start writing your code, and that's the only way you can really speed up writing code. If you first write the implementation of the code and somehow verify that it works, you might say to yourself, "Oh, it looks good-who needs testing?" I have more code to write! "The unfortunate side of this is that you usually do something to test your code, and you simply skip where you can automate testing.
AppFuse's documentation shows how to test all levels of an application. It starts with the database layer and uses DbUnit (see Resources) to populate your database with data before running the test. In the data access (DAO) layer, it uses the Spring AbstractTransactionalDataSourceSpringContextTests
class (yes, this is really the name of a Class!). ) to allow the Spring context file to be loaded simply. In addition, this class testXXX()
encapsulates a transaction for each method and rolls back when the test method exists. This feature makes testing the DAO logic very simple and does not affect the data in the database.
At the service level, jMock (see Resources) is used to write real unit tests that can eliminate DAO dependencies. This allows for quick testing of the correct business logic, and we don't have to worry about the underlying persistence logic.
Htmlunit Support
The Htmlunit team has done quite a lot of work in the 1.8 release to ensure that packages work well with popular Ajax frameworks (Prototype and scriptaculous).
At the WEB layer, the test verifies that the operation (Struts/webwork), the control (Spring MVC), the page (Tapestry), and the Management Bean (JSF) work as we expect. Spring's Spring-mock.jar can be very useful for testing all of these frameworks, as it contains a simulation implementation of a Servlet API. Without this useful library, it would be very difficult to test the AppFuse WEB framework.
The UI is often the most difficult part of developing a WEB application. It is also the place where customers complain most often-both because it is not perfect and because it works differently than we expect. Plus, there's nothing worse than seeing an exception stack in front of a customer for a demo! Your application can be scary, but customers may ask you to be perfect. Never let such a thing happen. Canoo WebTest can test the UI. It uses Htmlunit to traverse the test UI, verify that all elements are present, populate the form's domain, and even verify that an imaginary Ajax-enabled UI works the way we expect. (See Resources for links to WebTest and htmlunit.) )
To further simplify the testing of the Web, Cargo (see Resources) automates the start and stop of Tomcat (before and after running WebTest tests, respectively).
Back to top of page
Reason 2: Integration
As I mentioned in the introduction to this article, many open source repositories have been pre-integrated into AppFuse. They can be divided into the following categories:
- compiling, reporting, and code generation: Ant, Ant Contrib Tasks, Checkstyle, EMMA, java2html, PMD, and Rename Packages
- Test Framework: DbUnit, Dumbster, JMock, JUnit, and Canoo WebTest
- Database driver: MySQL and PostgreSQL
- Persistence Framework: Hibernate and IBATIS
- IoC Framework: Spring
- WEB Framework: JSF, Spring MVC, Struts, Tapestry, and WebWork
- Web Services: Xfire
- Web Tools: Clickstream, Display Tag, DWR, JSTL, Sitemesh, Struts Menu, and URL Rewrite Filter
- Security: Acegi Security
- JavaScript and CSS: CSS Framework for Scriptaculous, Prototype, and Mike Stenhouse
In addition to these libraries, AppFuse uses log4j to log logs, using Velocity to build e-mail and menu templates. Tomcat can support the latest development, and we can use the 1.4 or 5 version of the Java platform to compile or build the program. We should be able to deploy AppFuse to any Java 1.3 compatible application server; This has been tested and we know it works well on all major versions of the Java EE Server and all the major servlet containers.
Figure 3 shows the Lib directory for the Devworks project created above. The lib.properties file in this directory controls the version number of each dependency, which means that we can ant test-all -Dspring.version=2.0
test the new version of these packages simply by putting new versions of the packages into this directory and executing commands such as these.
Figure 3. Project Dependencies
Pre-integration of these open source repositories can greatly increase productivity at the beginning of the project. Although we can find a lot of documentation on how to integrate these libraries, it's much easier to customize the work sample and simply use it to develop the application.
In addition to simplifying the development of Web applications, AppFuse allows us to easily integrate Web services into our own projects. Although XFire is also available in the AppFuse download, if we wish, we can also integrate Apache axis ourselves (see Resources for a tutorial on Axis integration). In addition, the Spring framework and XFire can work together to present the service layer as a Web service very simply, which gives us the ability to develop a service-oriented architecture.
In addition, AppFuse does not restrict us to any particular API. It simply re-packs and pre-integrates the best open source solutions available. The code in AppFuse can handle this integration and implement the basic security and usability features of AppFuse. Whenever possible, the code is reduced to add an attribute to the AppFuse dependency framework. For example, AppFuse's own Remember Me and SSL switching features have recently been removed from Acegi Security because of similar features.
Back to top of page
Reason 3: Automation
Ant makes it easy to automate the process from compile to build to deployment. Ant is a prime citizen in AppFuse, mainly because I find it easier to perform operations on the command line than from the IDE. We can use ANT implementations to compile, test, deploy, and execute any code-generation tasks.
Although this ability is important to some people, it does not apply to all people. Many AppFuse users are currently using Eclipse or Intellij idea to build and test their own projects. Running Ant in these Ides does work, but it's often less efficient to run tests using the IDE's built-in JUnit support.
Fortunately, AppFuse supports running tests in the IDE, but managing this feature becomes very difficult for AppFuse developers. The biggest pain is the XDoclet used to generate Hibernate mapping files and Web frameworks used by some artifacts (such as the struts-config.xml used by Actionforms and Struts). The IDE does not know the code that needs to be generated, unless we have configured to use ANT to compile them, or have installed some plugins that recognize XDoclet.
This lack of knowledge is the main reason why AppFuse 2.0 switches to JDK 5 and Maven 2. JDK 5, annotations and Struts 2 will allow us to get rid of XDoclet. Maven 2 will use these generated files and dynamic classpath to build the IDE project file, which simplifies the management of the project. The current ANT-based build system has generated artifacts (including Dao.jar, Service.jar, and Webapp.war) for different levels, so switching to Maven's model should be a very natural adjustment.
In addition to ANT, which has extensive support for compilation, testing, deployment, and reporting, support for CruiseControl is also built into AppFuse. CruiseControl is an continuous integration application that allows us to run all tests automatically when the code changes in the source code repository. The Extras/cruisecontrol directory contains the files we need to quickly and easily set up continuous integration for AppFuse-based projects.
Setting continuous integration is one of the first things we need to do in the software development cycle. It not only inspires programmers to write test cases, but also facilitates collaboration and integration between teams through the "You broke the build!" game.
Back to top of page
Reason 4: Security features and scalability
AppFuse was originally developed as part of the sample application in the book Pro JSP I wrote for Apress. This sample application demonstrates a number of security features and features to simplify Struts development. Many of the security features in this application do not exist in the security block diagram of the Java EE. The authentication method using the Container management authentication (CMA) is very simple, but Remember Me, password hint, SSL switchover, registration, and user management are all non-existent. In addition, role-based protection method functionality is not possible in non-EJB environments.
Initially, AppFuse fully implemented these features using its own code and the solution for CMA. I heard about Acegi Security when I started learning Spring in early 2004. I compared the number of lines of XML required by Acegi (175) to the desired CMA line in Web. XML (20), and soon decided to discard Acegi because it was too complex.
After 1.5-after writing a chapter about using Acegi Security for another book, Spring Live -I changed my mind. Acegi does (still) need a lot of XML, but once we understand this, it's actually quite simple. We finally removed a lot of code after we finally made a change, using the Acegi Security feature to completely replace the AppFuse feature. The classes above the class are gone, and the missing parts of "Acegi handles that" are now all in the CVS Attic.
Acegi security is the best model ever seen in the Java EE Safety model. It allows us to implement a number of useful features that do not exist in the security model of the Servlet API: Authentication, Authorization, role protection methods, Remember Me, password encryption, SSL switchover, user Switching, and logoff. It also allows us to store user certificates in an XML file, database, LDAP, or Single sign-on system, such as Yale's central authentication Service (CAS) or SiteMinder.
AppFuse's implementation of many security-related features is excellent from the start. Now that AppFuse uses Acegi Security, these features--and more--are very easy to implement. Acegi can be expanded in many places: this is why it uses a huge XML configuration file. Just as we have integrated the Acegi through last year's course, we have found that customizing many bean definitions can be more closely linked to AppFuse.
The combination of simple development, easy-to-test code, and loose-coupling features provided by Spring IoC container and Acegi Security are the main reasons why AppFuse is such a good development platform. These frameworks are non-pluggable and allow the generation of clean testable code. AppFuse integrates many open source projects, and dependency injection allows for simple integration of the application layer.
Back to top of page
Reason 5: Generate code using AppGen
Some people call code generation called code smell. In their opinion, if we need to generate code, then it is possible to do something wrong. I tend to determine the pattern of my code usage and the ability to automate the generation of code that should be called code perfume. If we are writing a similar DAO, manager, action, or control and do not want to generate code for them, then it is necessary to generate code based on the smell of the code. Of course, when the language can provide us with features that simplify the task, everything is fine, but code generation is often a requirement--usually a very high productivity--task.
AppFuse provides an Ant-and XDoclet-based code generation tool called AppGen. By default, Common DAO and manager can allow us to CRUD on any ordinary old Java object (POJO), but it is difficult to do so on the Web tier. AppGen has several features that you can use to perform the following tasks:
- Generate POJO from database tables (using the Middlegen and Hibernate tools)
- Generate UI from POJO
- Generate tests for DAO, manager, Operations/controller, and UI
When you run AppGen, you'll see a prompt saying AppGen to generate code from a database table or POJO. If executed at the command line ant install-detailed
, AppGen installs POJO specific DAO, manager, and their tests. Running ant install
causes the WEB layer's classes to reuse common DAO and the default existing manager.
To illustrate how AppGen works, we created the table in the devworks MySQL database as shown in Listing 2:
Listing 2. Create a database table named Cat
CREATE TABLE Cat ( cat_id int (8) auto_increment, color varchar () Not NULL, name varchar () is not NULL, C Reated_date datetime NOT NULL, primary KEY (cat_id) ) Type=innodb;
In the Extras/appgen directory, run ant install-detailed
. The output of this command is too long for this article, but we gave the first part in Listing 3:
Listing 3. Install-detailed Target for running AppGen
$ ant install-detailedbuildfile:build.xmlinit: [mkdir] Created dir:/users/mraible/work/ Devworks/extras/appgen/build [echo] [echo] +-------------------------------------------------------+ [echo] | --Welcome to the appgen! -- | [Echo] | | [Echo] | Use the "Install" target to use the generic DAO and | [Echo] | Manager, or use ' install-detailed ' to general a DAO | [Echo] | and Manager specifically for your model object. | [echo] +-------------------------------------------------------+ [input] would you like to generate code from a table O R POJO? (table,pojo) Table [input] What is the name of your table (i.e)? cat [input] What's the name, if any, of the Module for your table (i.e. organization)? [Echo] Running Middlegen to generate POJO ...
To use this newly generated code for the cat table, we need to modify Src/dao/com/ibm/dao/hibernate/applicationcontext-hibernate.xml to add Cat.hbm.xml to hibernate The mapping file. Listing 3 shows the look of our modified sessionFactory
bean:
Listing 4. Add Cat.hbm.xml to the Sessionfactory bean
<bean id= "sessionfactory" class= "..." > <property name= "DataSource" ref= "DataSource"/> < Property name= "Mappingresources" > <list> <value>com/ibm/model/Role.hbm.xml</value> <value>com/ibm/model/User.hbm.xml</value> <value>com/ibm/model/Cat.hbm.xml</value> </list> </property> ...</bean>
After running ant setup deploy
, we should be able to perform CRUD operations on cat tables in the deployed application:
Figure 4. Cat List
Figure 5. Cat Forms
The records we saw in the screenshot above were created as part of the code generation, so now we have the test data.
Back to top of page
Reason 6: Documentation
We can find tutorials on the various flavors of AppFuse, and they are given in 6 different languages: Chinese, German, English, Korean, Portuguese and Spanish. Using the word flavor (flavor) , I mean a combination of different frameworks, such as spring MVC plus IBATIS, spring MVC plus hibernate or JSF plus hibernate. There are several combinations of these 5 Web frameworks and two durable frameworks. For their translations, AppFuse provides 8 translations for its default features. Available languages include Chinese, Dutch, German, English, French, Italian, Portuguese, and Spanish.
In addition to the core tutorials, a number of tutorials have been added (see Resources) to introduce integration with various databases, application servers, and other open source technologies, including JasperReports, Lucene, Eclipse, Drools, Axis, and DWR.
Back to top of page
Reason 7: Community
The Apache Software Foundation has an interesting view of open source. It is most interested in developing an open source community around open source projects. Its members believe that if the community is very powerful, then producing high-quality code is a natural process. The following is a quote from the Apache home page:
"We think of ourselves as more than just a set of shared server projects, but also a community of developers and users. "
The AppFuse community has gained tremendous growth since 2003 as a project on SourceForge (part of the struts.sf.net). By converting to java.net in March 2004, it has become a very popular project here, with the largest number of visits from January 2005 to March. It is still a very popular project (see Resources for a link to java.net project statistics), but on this site it is making many projects that are sponsored by Sun.
At the end of 2004, Nathan Anderson became the first submitter following me. Since then, a lot of people have joined in, including Ben Gill, David Carter, Mika G?ckel, Sanjiv Jivan and Thomas Gaudin. Many of the existing contributors have made their contribution in various ways, and they have helped the AppFuse community become a rapidly changing and interesting place.
The mailing list is very friendly, and we are trying to maintain a commitment that "no problem is no one's concern". The only one by one "RTFM" in our mailing list archive is sent from the user, not from the developer. We absolutely believe in the Apache open source community philosophy. Quoting the words of my best friend Bruce Snyder, "We come for the code and stay for the people." At the moment, most developers are users, and we usually like to have a wonderful time. In addition, most documents are written by the community, so the knowledge of the community is very profound.
Back to top of page
Conclusion
We should try to develop with AppFuse because it allows us to simply test, integrate, automate, and safely build WEB applications. Its documentation is very rich and the community is very friendly. As its support framework gets better, AppFuse will continue to improve.
Starting with AppFuse 2.0, we plan to migrate to JDK 5 (which still supports deployment to 1.4) and Maven 2 up. These tools can simplify the development, installation, and upgrade of using AppFuse. We plan to take full advantage of the capabilities of Maven 2 to handle related dependencies. We will encounter artifacts such as Appfuse-hibernate-2.0.jar and Appfuse-jsf-2.0.jar. These artifacts can be referenced in the Pom.xml file, and they are responsible for extracting other dependent dependencies. In addition to using the AppFuse base class in our own projects, we can simply extend these classes in jars like normal frameworks, which should greatly simplify the upgrade process and encourage more users to submit their desired improvements to this project.
If there are no other problems, using AppFuse will keep you on the cutting edge of Java Web development-just like us!
Reference Learning
- You can refer to the original English text on the DeveloperWorks global site in this article.
- AppFuse: The project's home page.
- AppFuse Demos: View demos and videos.
- Struts 2 and JSF: Learn why you want to work together on these technologies.
- Sun's Java EE project directory structure guide: AppFuse is very close to these guidelines.
- Maven's standard directory Layout:appfuse 2.0 will be converted to this directory structure.
- AppFuse Quick Start Guide: Get started quickly and use AppFuse.
- AppFuse Tutorial: Learn more about using AppFuse in depth.
- Apache Axis integration: How to integrate Apache axis into your own AppFuse project.
- java.net Project Status: See the January 2005, February, and March developments. You can also view the best items on the java.net.
Access to products and technologies
- AppFuse on java.net: Download different flavors of AppFuse.
- WebWork: Learn about this easy-to-use WEB framework.
- DbUnit: See more about the JUnit extensions.
- JMock: Create dynamic simulation objects to simplify real unit testing.
- Canoo WebTest: UI testing for automated WEB applications.
- The foundation behind Htmlunit:webtest's excellent JavaScript support.
- Cargo: Automatically starts and stops containers.
- Greenbox: A code generation framework.
Discuss
- AppFuse Forum: Communicate skills with fellow developers.
Seven reasons to use AppFuse