安装、配置好appfuse后,按一下步骤使用:
1 创建项目
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes
-DarchetypeArtifactId=appfuse-basic-struts
-DremoteRepositories=http://static.appfuse.org/releases
-DarchetypeVersion=2.0.2
-DgroupId=com.mycompany1.app
-DartifactId=myproject1
2 运行项目
如果mysql的root用户有口令,在pom.xml文件设置口令。如下:
<jdbc.username>root</jdbc.username>
<jdbc.password>123456</jdbc.password>
进入项目所在目录,运行以下命令:
mvn jetty:run-war
打开浏览器上,从以下连接进入: http://localhost:8080
3 将appfuse的源码装入项目
执行以下命令,将appfuse的源码装入项目的源码装入项目。
mvn appfuse:full-source
这个命令完成以下功能:
1. 将dao 、service、web的基础代码装入项目.
2. 将这些类的包名改为项目自己的包名.
4 代码生成
AMP(The AppFuse Maven Plugin) plugin currently does two things:
1) code generation for CRUD and
2) allows you to convert your project to use AppFuse's source instead of using its binary dependencies.
4.1 Generating CRUD with AMP
4.1.1 生成pojo类
首先,创建表:
CREATE TABLE `Mmployee` (
`id` bigint(20) NOT NULL auto_increment,
`code` varchar(10) NOT NULL,
`dept` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`status` varchar(10) NOT NULL,
`telephone` varchar(20) default NULL,
`title` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
There's also a goal that allows you to generate model objects from database tables.
mvn appfuse:gen-model
提示如下:
E:\DevelopSrc\myproject1>mvn appfuse:gen-model
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'appfuse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building AppFuse Struts 2 Application
[INFO] task-segment: [appfuse:gen-model]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing appfuse:gen-model
[INFO] [warpath:add-classes {execution: default}]
[INFO] [aspectj:compile {execution: default}]
[INFO] [native2ascii:native2ascii {execution: native2ascii-utf8}]
[INFO] [native2ascii:native2ascii {execution: native2ascii-8859_1}]
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [appfuse:gen-model]
[INFO] Configuration XML file loaded: file:/E:/DevelopSrc/myproject1/src/main/re
sources/hibernate.cfg.xml
[INFO] Configuration Properties file loaded: E:\DevelopSrc\myproject1\target\cla
sses\jdbc.properties
[INFO] Copying generated 'Employee.java' to project...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13 seconds
[INFO] Finished at: Wed Dec 31 15:43:35 CST 2008
[INFO] Final Memory: 19M/36M
[INFO] ------------------------------------------------------------------------
This goal will install the generated files into your source tree, unless you specify
-DdisableInstallation=true. After running this command, you can use appfuse:gen to generate
CRUD classes/tests/screens for this object.
4.1.2 生成基本的 dao、service、struts代码
You can run the following command to generate CRUD screens/classes for a POJO:
mvn appfuse:gen -Dentity=Name
If you don't specify the entity name, you will be prompted for it. Currently, if a @Column has "nullable =
false", a "required field" validation rule will be generated as part of the web framework's validation
configuration. This command will also install the generated code, unless you specify
-DdisableInstallation=true.
If your entity is not defined in hibernate.cfg.xml, it will be added.
In a modular project, these commands must be run in the "core" and "web" modules. The plugin is smart
enough to figure out when it should/should not generate stuff based on the packaging type (jar vs. war).
If you want to generate specific code in a "war" project, you can use gen-core or gen-web.
接前一步,执行:
mvn appfuse:gen -Dentity=Employee
提示如下:
E:\DevelopSrc\myproject1>mvn appfuse:gen
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'appfuse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building AppFuse Struts 2 Application
[INFO] task-segment: [appfuse:gen]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing appfuse:gen
[INFO] [warpath:add-classes {execution: default}]
[INFO] [aspectj:compile {execution: default}]
[ERROR] Duplicate annotation @GeneratedValue
[ERROR] Duplicate annotation @GeneratedValue
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Compiler errors :
error at @Id @GeneratedValue(strategy=IDENTITY) @GeneratedValue(strategy = Gener
ationType.AUTO)
^^^^^^^^^^
E:\DevelopSrc\myproject1\src\main\java\com\mycompany1\app\model\Employee.java:28
:0::0 Duplicate annotation @GeneratedValue
error at @Id @GeneratedValue(strategy=IDENTITY) @GeneratedValue(strategy = Gener
ationType.AUTO)
^^^^^^^^^^
E:\DevelopSrc\myproject1\src\main\java\com\mycompany1\app\model\Employee.java:28
:0::0 Duplicate annotation @GeneratedValue
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8 seconds
[INFO] Finished at: Wed Dec 31 15:53:08 CST 2008
[INFO] Final Memory: 18M/33M
[INFO] ------------------------------------------------------------------------
出了错误。查看原代码,原来model中有两个ID的生成策略,如下:
@Id @GeneratedValue(strategy=IDENTITY) @GeneratedValue(strategy = GenerationType.AUTO)
删除@GeneratedValue(strategy=IDENTITY),只剩下一个。
再执行 mvn appfuse:gen -Dentity=Employee。
失败,出现以下错误提示:
E:\DevelopSrc\myproject1> mvn appfuse:gen
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'appfuse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building AppFuse Struts 2 Application
[INFO] task-segment: [appfuse:gen]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing appfuse:gen
[INFO] [warpath:add-classes {execution: default}]
[INFO] [aspectj:compile {execution: default}]
[INFO] [native2ascii:native2ascii {execution: native2ascii-utf8}]
[INFO] [native2ascii:native2ascii {execution: native2ascii-8859_1}]
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [appfuse:gen]
What is the name of your pojo (i.e. Person)?: Employee
Property 'http://apache.org/xml/features/nonvalidating/load-external-dtd' is not recognized.
org.xml.sax.SAXNotRecognizedException: Property 'http://apache.org/xml/features/nonvalidating/load-external-dtd' is not recognized.
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.getProperty(AbstractSAXParser.java:2060)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.setProperty(SAXParserImpl.java:467)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.setProperty(SAXParserImpl.java:263)
at org.appfuse.mojo.exporter.AppFuseGeneratorMojo$POJOSearcher.searchForPojo(AppFuseGeneratorMojo.java:384)
at org.appfuse.mojo.exporter.AppFuseGeneratorMojo.addEntityToHibernateCfgXml(AppFuseGeneratorMojo.java:298)
at org.appfuse.mojo.exporter.AppFuseGeneratorMojo.execute(AppFuseGeneratorMojo.java:165)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
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 org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
[INFO] [AppFuse] Found 'Employee.java' in model package...
[INFO] [AppFuse] Adding 'Employee' to hibernate.cfg.xml...
log4j:WARN Continuable parsing error 57 and column 64
log4j:WARN Attribute value "com.opensymphony.xwork2.util.OgnlValueStack" of type ID must be unique within the document.
[INFO] Configuration XML file loaded: file:/E:/DevelopSrc/myproject1/src/main/resources/hibernate.cfg.xml
[INFO] Configuration XML file loaded: file:/E:/DevelopSrc/myproject1/src/main/resources/hibernate.cfg.xml
[INFO] src/main/resources/database.properties not found within the project. Trying absolute path.
[INFO] No hibernate properties file loaded.
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] null
Illegal character in path at index 18: file:/C:/Documents and Settings/wuqinglin
/.m2/repository/org/apache/ant/ant/1.7.0/ant-1.7.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.IllegalArgumentException
at java.net.URI.create(URI.java:842)
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 org.apache.tools.ant.launch.Locator.fromURI(Locator.java:162)
at org.apache.tools.ant.launch.Locator.getResourceSource(Locator.java:119)
at org.apache.tools.ant.launch.Locator.getClassSource(Locator.java:90)
at org.apache.tools.ant.Project.setAntLib(Project.java:313)
at org.apache.tools.ant.Project.initProperties(Project.java:309)
at org.apache.tools.ant.Project.init(Project.java:295)
at org.appfuse.mojo.installer.AntUtils.createProject(AntUtils.java:47)
at org.appfuse.tool.ArtifactInstaller.copyGeneratedObjects(ArtifactInsta
ller.java:109)
at org.appfuse.tool.ArtifactInstaller.execute(ArtifactInstaller.java:44)
at org.appfuse.mojo.exporter.AppFuseGeneratorMojo.doExecute(AppFuseGener
atorMojo.java:270)
at org.appfuse.mojo.HibernateExporterMojo.execute(HibernateExporterMojo.
java:138)
at org.appfuse.mojo.exporter.AppFuseGeneratorMojo.execute(AppFuseGenerat
orMojo.java:210)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPlugi
nManager.java:451)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(Defa
ultLifecycleExecutor.java:558)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandalone
Goal(DefaultLifecycleExecutor.java:512)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(Defau
ltLifecycleExecutor.java:482)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHan
dleFailures(DefaultLifecycleExecutor.java:330)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegmen
ts(DefaultLifecycleExecutor.java:291)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLi
fecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
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 org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: java.net.URISyntaxException: Illegal character in path at index 18: f
ile:/C:/Documents and Settings/wuqinglin/.m2/repository/org/apache/ant/ant/1.7.0
/ant-1.7.0.jar
at java.net.URI$Parser.fail(URI.java:2809)
at java.net.URI$Parser.checkChars(URI.java:2982)
at java.net.URI$Parser.parseHierarchical(URI.java:3066)
at java.net.URI$Parser.parse(URI.java:3014)
at java.net.URI.<init>(URI.java:578)
at java.net.URI.create(URI.java:840)
... 34 more
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27 seconds
[INFO] Finished at: Wed Dec 31 16:18:44 CST 2008
[INFO] Final Memory: 19M/35M
[INFO] ------------------------------------------------------------------------
原因:
上面的问题有两个:
1 org.xml.sax.SAXNotRecognizedException:
是因为jdk的问题,jdk5不会出现这问题。
2 java.lang.IllegalArgumentException:
是ant的bug,路径里面不能有空格,因为Documents and Settings里面有空格所以报错。
直接把repository文件夹拷贝到 E:\AppfuseEnv\repository。
然后,在E:\AppfuseEnv\Tools\apache-maven-2.0.9\conf的settings.xml修改如下:
!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ~/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>E:\AppfuseEnv\repository</localRepository>
搞定,但是,
注意:如果你希望appfuses生成 dao 和 service 类,就在项目根目录下的pom.xml中,把genericCore属性设为false。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appfuse-maven-plugin</artifactId>
<version>${appfuse.version}</version>
<configuration>
<genericCore>${amp.genericCore}</genericCore>
<fullSource>${amp.fullSource}</fullSource>
</configuration>
</plugin>
如果 DAOs and Managers 不是使用基础公用类(也就是GenericManagerImpl或者UniversalManagerImpl),那么amp.genericCore的属性值设置为false。这样会生成单独的DAOs and Managers类,以方便加入代码。否则设置为true。
如果已经执行过 mvn appfuse:full-source 命令,则 amp.fullSource 的属性值设置 true。它会将你的代码中的“org.appfuse”包名前缀修改为你自己的包名。
4.1.3 Removing Code
You can run mvn appfuse:remove to remove the artifacts installed by appfuse:gen.
5 定制模板
If you want to customize the code generation templates (written in FreeMarker), you can copy them into
your project using the following command:
mvn appfuse:copy-templates