標籤:
AppFuse是一個使用Java語言開發web應用系統的整合架構。java開發人員最頭痛的事情就是面對大量的架構不知該如何選擇。這些架構效能如何,相容性如何等等都需要篩選比較。Appfuse作者Matt Raible對於這些架構做了深入研究,把這些架構中最優秀的部分拿出來整合到一起,形成了最優秀的整合架構。目前這個架構的最新穩定版本是3.5.
AppFuse中的基礎架構:
- Bootstrap 和jQuery
- Maven, Hibernate, Spring 和Spring Security
- Java 7, Annotations, JSP 2.1, Servlet 3.0
- Web架構: GWT, JSF, Struts 2, Spring MVC, Tapestry 5, Wicket
- JPA
AppFuse提供了許多應用需要的開箱即用的功能,包括:
- 驗證和授權
- 使用者管理
- 記住我 (儲存登入資訊,不必每次都登入)
- 密碼提示
- 註冊和登記
- SSL切換
- 電子郵件
- Extension-less URLs (不知道該怎麼翻譯,求助!!!)
- 檔案上傳
- 產生CRUD後端
- 完全支援Eclipse, IDEA 和NetBeans
- 使用Maven和Jetty等外掛程式,進行快速啟動和部署
- 使用Cargo以及Maven的多模式選項(profiles)支援多種前台應用和多種資料庫的選擇部署,並且做到可測試
最新的AppFuse和Maven關係緊密。幾乎所有的操作都通過Maven來執行,所以要對Maven以及模組化開發有一定的瞭解,對Maven profiles有比較深入的瞭解,對Maven的倉庫結構也需要有一定瞭解。
AppFuse支援多種資料庫(Derby、H2、HSQLDB、MySQL、Oracle、PostgreSQL、SQL Server),預設資料庫是MySQL。在我切換到Oracle資料庫的時候,發現了一下問題,才有了此文。下面我介紹發現的問題和解決方案。
1.首先下載安裝Maven 3.1.0+,網上有很多教程,這裡就不贅述了。當然,你還需要JDK7+, MySQL 5.5+ 。
2.使用Maven產生包含AppFuse架構的空項目:
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-modular-spring-archetype -DarchetypeVersion=3.5.0 -DgroupId=com.myCompany.myProject -DartifactId=myProject -DarchetypeRepository=https://oss.sonatype.org/content/repositories/appfuse
首先解釋一下:這是個mvn產生(archetype:generate)架構代碼的命令,後續會用到。其中myCompany是公司名稱,myProject是項目名稱。AppFuse版本是3.5.0。最關鍵的部分是appfuse-modular-spring-archetype,modular代表多模組,spring代表前段架構是spring MVC。
啟動命令列(cmd)。修改目前的目錄到Java的workspace(你想要放置代碼的目錄)。輸入上面的一大串以mvn開頭的字元,斷行符號。由於天朝眾人皆知的原因和Google的退出,有些jar包可能找不到源頭,可能你被迫必須FQ(FreeGate)才能完成這個命令。也可能由於網速太慢,下載逾時,你需要反覆嘗試上面的命令。
總之,需要艱辛的努力,還可能需要一些非常規手段。。。
神奇的事情發生了,你發現你的workspace下面多了一個檔案夾。
別著急,你還需要小小的幾步。
3.下載架構中用到的原始碼和模板。
mvn appfuse:full-source
這個時候如果系統運行環境JDK和資料庫MySql(root的密碼為空白)已經準備好,就可以到web目錄下運行命令mvn jetty:run部署啟動項目,登入http://localhost:8080訪問你的項目了!
4.產生專案檔。
命令列目前的目錄切換到myproject目錄下。如果你使用的是eclipse,你可以運行:mvn eclipse:eclipse 命令。如果你使用的是idea,運行:mvn idea:idea。專案檔和相關依賴會產生。
5.切換到Oracle資料庫。
AppFuse為我們準備了多款資料庫選擇(profiles)。查看這些profiles,可以鍵入以下命令:
mvn help:full-profiles
顯示全部可以profiles。
mvn help:active-profiles
顯示啟用的profiles。
本來事情很簡單,我們只需要執行以下命令即可切換到oracle.
mvn clean install -P oracle
清除項目產生的檔案,並安裝oracle Profile。
但執行過程中報了三個錯誤,導致執行失敗。
問題1:找不到odbc jar包。
我們到Maven的倉庫中找到oracle相關的倉庫:C:\Users\[localUser]\.m2\repository\com\oracle\ojdbc14\10.2.0.2.0。這個倉庫是由AppFuse產生的,但下面缺少Jar包。我們需要從Oracle網站上下載一個10.2.0.2.0版本對應的ojdbc14-.jar放到這個目錄下面,並且改名為:ojdbc14-10.2.0.2.0.jar。
也有人覺得現在oracle版本已經12了,還用10的驅動,有點過時。你可以安裝自己的oracle庫。方法是下載oracle相應jar,執行maven命令安裝jdbc依賴。我正好安裝了oracle資料庫11.2G,就用它的驅動了,省的下載。
mvn install:install-file -Dfile=C:\app/[localUser]/product/11.2.0/dbhome_1/jdbc/lib/ojdbc6_g.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar
如果你本機沒有裝Oracle,或者全域資料庫名不是XE,你可能需要修改預設的資料庫連接選項。開啟檔案:C:\Users\[localUser]\.m2\repository\org\appfuse\appfuse\3.5.0\appfuse-3.5.0.pom。做好備份。找到oracle相關的profile,修改成下面的樣子:
<profile> <id>oracle</id> <properties> <dbunit.dataTypeFactoryName>org.dbunit.ext.oracle.OracleDataTypeFactory</dbunit.dataTypeFactoryName> <dbunit.schema>MYPROJECT</dbunit.schema> <!-- Make sure to capitalize the schema name --> <!--<dbunit.operation.type>CLEAN_INSERT</dbunit.operation.type>--> <hibernate.dialect>org.hibernate.dialect.Oracle10gDialect</hibernate.dialect> <hibernate.export.schema.delimiter></hibernate.export.schema.delimiter> <jdbc.groupId>com.oracle</jdbc.groupId> <jdbc.artifactId>ojdbc6</jdbc.artifactId> <jdbc.version>11.2.0</jdbc.version> <jdbc.driverClassName>oracle.jdbc.OracleDriver</jdbc.driverClassName> <jdbc.url><![CDATA[jdbc:oracle:thin:@localhost:1521:Orcl]]></jdbc.url> <jdbc.username>myproject</jdbc.username> <jdbc.password>myproject</jdbc.password> <jdbc.validationQuery><![CDATA[SELECT 1 + 1 from DUAL]]></jdbc.validationQuery> </properties> </profile>
其中myproject是我專門為該項目建立的資料庫。本機資料庫的全域執行個體名是orcl。jdbc也改成了11.2的。還有一些更改後續會提到。
問題2:資料庫指令碼無法執行。到myproject\core\target目錄下,找到schema.sql。開啟查看,發現一切正常,你到sqlplus下面執行這個sql檔案也沒有問題。
檔案發生的原因是這個sql不是由sqlplus執行的,而是2.有hibernate執行的!hibernate執行sql語句的時候,不能有段落結束符合“;”。所以報錯!解決辦法是在appfuse-3.5.0.pom中的oracle profile中增加一個設定,把段落分割符設定成空:
<hibernate.export.schema.delimiter></hibernate.export.schema.delimiter>
這樣問題就解決了!
問題3:單元測試不能通過。報一個奇怪的錯誤:
Tests run: 9, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.167 sec <<< FAILURE!
testUpdateUser(com.exam.dao.UserDaoTest) Time elapsed: 0.088 sec <<< ERROR!
java.lang.Exception: Unexpected exception, expected<org.springframework.dao.DataIntegrityViolationException> but was<org.springframework.orm.hibernate4.HibernateSystemException>
這個問題已經被提交到AppFuse的郵件清單中,但是還沒有正面的回複,只有一個規避的辦法。深層次的原因需要有能力的人繼續挖掘!
規避辦法是注釋掉測試代碼UserDaoTest.java的第68行://user2.setRoles(user.getRoles());
user2.setLastName(user.getLastName()); user2.setPassword(user.getPassword()); user2.setPasswordHint(user.getPasswordHint()); //user2.setRoles(user.getRoles()); user2.setUsername(user.getUsername()); user2.setWebsite(user.getWebsite());
修改了這幾個問題,oracle profile就會成功啟用,測試通過並產生jar包、war包。
另外,我修改oracle資料庫profile(appfuse-3.5.0.pom)的方式比較不可取,更科學的方式是修改myproject下面的pom.xml.
<properties>
...其他設定
<!-- 為連結oracle資料庫添加了以下設定項,這些設定項的預設值指向mysql資料庫 --> <dbunit.dataTypeFactoryName>org.dbunit.ext.oracle.OracleDataTypeFactory</dbunit.dataTypeFactoryName> <dbunit.schema>MYPROJECT</dbunit.schema> <hibernate.dialect>org.hibernate.dialect.Oracle10gDialect</hibernate.dialect> <jdbc.groupId>com.oracle</jdbc.groupId> <jdbc.artifactId>ojdbc6</jdbc.artifactId> <jdbc.version>11.2.0</jdbc.version> <jdbc.driverClassName>oracle.jdbc.OracleDriver</jdbc.driverClassName> <jdbc.url><![CDATA[jdbc:oracle:thin:@localhost:1521:Orcl]]></jdbc.url> <jdbc.username>myproject</jdbc.username> <jdbc.password>myproject</jdbc.password> <jdbc.validationQuery><![CDATA[SELECT 1 + 1 from DUAL]]></jdbc.validationQuery> </properties>
AppFuse3.5對接oracle資料庫