JBoss Forge 1.0.0.Beta4を試す
JBoss Advent Calendar 2011の20日目のエントリです。JBoss Forge 1.0.0.Beta4がリリースされたので試してみます。
JBoss Forgeは超速Java EEアプリケーション開発を実現するためのツールです。元々Seam Forgeという名前でSeamのサブプロジェクトとして開発されたのですが、Seamへの依存は無く、JBossのプロジェクトとして独立しました。
さて、起動してみましょう。zipダウンロードして展開してJBOSS_HOMEを指定して起動します。
$ cd ~/tmp $ wget "https://repository.jboss.org/nexus/service/local/artifact/maven/redirect?r=releases&g=org.jboss.forge&a=forge-distribution&v=1.0.0.Beta4&e=zip" $ unzip forge-distribution-1.0.0.Beta4.zip $ JBOSS_HOME=/home/nekop/jboss710b1b ./forge-distribution-1.0.0.Beta4/bin/forge Using Forge at /home/nekop/usr/local/forge-distribution-1.0.0.Beta4 _____ | ___|__ _ __ __ _ ___ | |_ / _ \| `__/ _` |/ _ \ \\ | _| (_) | | | (_| | __/ // |_| \___/|_| \__, |\___| |___/ [no project] tmp $
Forgeはおおざっぱに以下の流れで利用します。
Forgeを使ってプロジェクトを作成すると、そのプロジェクトへサポートされるテクノロジを自由に追加できます。例えば以下のように実行すると、現在のプロジェクトにJPAのサポートが追加されます。
$ persistence setup --provider HIBERNATE --container JBOSS_AS7 ;
コマンド一覧はlist-commandsコマンドで出力されます。
$ list-commands
さて、GitHub上のショーケースのサンプルを実行してみます。名前とパッケージ名は適当に"foo"と入れました。
[no project] tmp $ run-url https://raw.github.com/forge/core/master/showcase/posale.fsh Wrote /tmp/tempc726d6b63a8d405e87f1106dcf2880bf ? [named=The name of the new project (of type java.lang.String)]: foo ? [topLevelPackage=The top-level java package for the project [e.g: "com.example.project"] (of type java.lang.String)]: foo ? Use [/home/nekop/tmp/foo] as project directory? [Y/n] ***SUCCESS*** Created project [foo] in new working directory [/home/nekop/tmp/foo] Wrote /home/nekop/tmp/foo Wrote /home/nekop/tmp/foo/pom.xml Wrote /home/nekop/tmp/foo/src/main/java Wrote /home/nekop/tmp/foo/src/test/java Wrote /home/nekop/tmp/foo/src/main/resources Wrote /home/nekop/tmp/foo/src/test/resources Wrote /home/nekop/tmp/foo/src/main/resources/META-INF/forge.xml ? Scaffold provider [faces] is not installed. Install it? [Y/n] ? Facet [forge.maven.WebResourceFacet] requires packaging type(s) [war], but is currently [jar]. Update packaging? (Note: this could deactivate other plugins in your project.) [Y/n] ***SUCCESS*** Installed [forge.maven.WebResourceFacet] successfully. Warning: The encoding 'UTF-8' is not supported by the Java runtime. ***SUCCESS*** Installed [forge.spec.jpa] successfully. ***SUCCESS*** Installed [forge.spec.ejb] successfully. ***SUCCESS*** Installed [forge.spec.cdi] successfully. Warning: The encoding 'UTF-8' is not supported by the Java runtime. ***SUCCESS*** Installed [forge.spec.servlet] successfully. ***SUCCESS*** Installed [forge.spec.jsf] successfully. ***SUCCESS*** Installed [faces] successfully. Warning: The encoding 'UTF-8' is not supported by the Java runtime. Warning: The encoding 'UTF-8' is not supported by the Java runtime. Wrote /home/nekop/tmp/foo/src/main/webapp Wrote /home/nekop/tmp/foo/pom.xml Wrote /home/nekop/tmp/foo/src/main/resources/META-INF/persistence.xml Wrote /home/nekop/tmp/foo/src/main/webapp/WEB-INF/beans.xml Wrote /home/nekop/tmp/foo/src/main/webapp/WEB-INF/web.xml Wrote /home/nekop/tmp/foo/src/main/webapp/WEB-INF/faces-config.xml Wrote /home/nekop/tmp/foo/src/main/webapp/favicon.ico Wrote /home/nekop/tmp/foo/src/main/webapp/resources/scaffold/paginator.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/resources/scaffold/page.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/index.html Wrote /home/nekop/tmp/foo/src/main/webapp/index.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/error.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/resources/background.gif Wrote /home/nekop/tmp/foo/src/main/webapp/resources/favicon.ico Wrote /home/nekop/tmp/foo/src/main/webapp/resources/forge-logo.png Wrote /home/nekop/tmp/foo/src/main/webapp/resources/forge-style.css Wrote /home/nekop/tmp/foo/src/main/webapp/resources/jboss-community.png Wrote /home/nekop/tmp/foo/src/main/webapp/resources/search.png ***INFO*** Setting transaction-type="JTA" ***INFO*** Using example data source [java:jboss/datasources/ExampleDS] Warning: The encoding 'UTF-8' is not supported by the Java runtime. ? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] ***SUCCESS*** Persistence (JPA) is installed. Wrote /home/nekop/tmp/foo/src/main/resources/META-INF/persistence.xml Created @Entity [foo.domain.Customer] Picked up type <JavaResource>: foo.domain.Customer Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Added field to foo.domain.Customer: @Column private String firstName; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Added field to foo.domain.Customer: @Column private String lastName; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Added field to foo.domain.Customer: private @Temporal(TemporalType.DATE) Date birthDate; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Created @Entity [foo.domain.Item] Picked up type <JavaResource>: foo.domain.Item Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Item.java Added field to foo.domain.Item: @Column private String name; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Item.java Added field to foo.domain.Item: @Column private Double price; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Item.java Added field to foo.domain.Item: @Column private int stock; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Item.java Created @Entity [foo.domain.ProductOrder] Picked up type <JavaResource>: foo.domain.ProductOrder Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ProductOrder.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ProductOrder.java Created @Entity [foo.domain.Profile] Picked up type <JavaResource>: foo.domain.Profile Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Profile.java Added field to foo.domain.Profile: @Column private String bio; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Profile.java Added field to foo.domain.Profile: @Column private String preferredName; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Profile.java Added field to foo.domain.Profile: @Column private String notes; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Profile.java Created @Entity [foo.domain.Address] Picked up type <JavaResource>: foo.domain.Address Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Address.java Added field to foo.domain.Address: @Column private String street; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Address.java Added field to foo.domain.Address: @Column private String city; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Address.java Created @Entity [foo.domain.ZipCode] Picked up type <JavaResource>: foo.domain.ZipCode Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ZipCode.java Added field to foo.domain.ZipCode: @Column private int code; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ZipCode.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Address.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Added field to foo.domain.Customer: @OneToOne private Profile profile; Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ProductOrder.java Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ProductOrder.java ***SUCCESS*** Generated UI for [foo.domain.Address] ***SUCCESS*** Generated UI for [foo.domain.ZipCode] ***SUCCESS*** Generated UI for [foo.domain.Profile] ***SUCCESS*** Generated UI for [foo.domain.Item] ***SUCCESS*** Generated UI for [foo.domain.ProductOrder] ***SUCCESS*** Generated UI for [foo.domain.Customer] Wrote /home/nekop/tmp/foo/src/main/java/foo/view/AddressBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/address/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/address/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/address/search.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/resources/scaffold/page.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/view/ViewUtils.java Wrote /home/nekop/tmp/foo/src/main/webapp/WEB-INF/classes/META-INF/forge.taglib.xml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Address.java Wrote /home/nekop/tmp/foo/src/main/java/foo/view/ZipCodeBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/zipCode/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/zipCode/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/zipCode/search.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ZipCode.java Wrote /home/nekop/tmp/foo/src/main/java/foo/view/ProfileBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/profile/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/profile/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/profile/search.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Profile.java Wrote /home/nekop/tmp/foo/src/main/java/foo/view/ItemBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/item/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/item/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/item/search.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Item.java Wrote /home/nekop/tmp/foo/src/main/java/foo/view/ProductOrderBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/productOrder/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/productOrder/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/productOrder/search.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/ProductOrder.java Wrote /home/nekop/tmp/foo/src/main/java/foo/view/CustomerBean.java Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/customer/create.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/customer/view.xhtml Wrote /home/nekop/tmp/foo/src/main/webapp/scaffold/customer/search.xhtml Wrote /home/nekop/tmp/foo/src/main/java/foo/domain/Customer.java [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for foo:foo:war:1.0.0-SNAPSHOT [WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-war-plugin is missing. @ line 74, column 15 [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building foo 1.0.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ foo --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 2 resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ foo --- [WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent! [INFO] Compiling 13 source files to /home/nekop/tmp/foo/target/classes [INFO] [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ foo --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ foo --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ foo --- [INFO] Surefire report directory: /home/nekop/tmp/foo/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- There are no tests to run. Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-war-plugin:2.1.1:war (default-war) @ foo --- [INFO] Packaging webapp [INFO] Assembling webapp [foo] in [/home/nekop/tmp/foo/target/foo] [INFO] Processing war project [INFO] Copying webapp resources [/home/nekop/tmp/foo/src/main/webapp] [INFO] Webapp assembled in [27 msecs] [INFO] Building war: /home/nekop/tmp/foo/target/foo.war [INFO] WEB-INF/web.xml already added, skipping [INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ foo --- [INFO] Installing /home/nekop/tmp/foo/target/foo.war to /home/nekop/.m2/repository/foo/foo/1.0.0-SNAPSHOT/foo-1.0.0-SNAPSHOT.war [INFO] Installing /home/nekop/tmp/foo/pom.xml to /home/nekop/.m2/repository/foo/foo/1.0.0-SNAPSHOT/foo-1.0.0-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.112s [INFO] Finished at: Tue Dec 20 11:36:58 JST 2011 [INFO] Final Memory: 10M/499M [INFO] ------------------------------------------------------------------------ ***SUCCESS*** Build successful.
デプロイしてみます。
[foo] foo $ as7 deploy Wrote /home/nekop/jboss710b1b/standalone/deployments/foo.war ***SUCCESS*** Deployed [foo.war] to [/home/nekop/jboss710b1b/standalone/deployments]
アクセスするとこんな感じのテンプレート画面が表示されますが、左下にエンティティの一覧があって、クリックするとそれぞれのデータの操作画面になります。
Addressをクリックするとこんな感じ。データが一覧表示され、検索とデータの操作ができるようになっています。
ショーケースの例もそうですが、Forgeを利用する一連の手順をスクリプト化してどこでも再現できる、という面白い機能があります。デモを行うときに便利ですし、スクリプトを流すだけなのでハンズオンも簡単、さらにスクリプトファイルをちょこちょこ変えるだけで似たようなプロジェクトが作れます。僕はJPAのテストをしたりだとか、ちょこっと機能を試すだけのプロジェクトを生成したりするのに使っています。
https://raw.github.com/forge/core/master/showcase/posale.fsh
また、Forgeのシェル環境ではGitが普通に使えるので、何かを試してイマイチだったら捨てる、というのが高速に行えるようになっています。
Forge(というかこの手の開発支援ツール全てに当てはまると思いますが)は慣れるまで多少時間がかかりますが、慣れてしまえば超速Java EEアプリケーション開発の恩恵を受けることができて便利ですね。