使用MDA方式开发软件

AppFuse

mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring-archetype -DarchetypeVersion=2.2.2-SNAPSHOT -DgroupId=com.mycompany -DartifactId=WillTestProject -DarchetypeRepository=http://oss.sonatype.org/content/repositories/appfuse

Andromda

Andromda hosted at Sonatype repository

Andromda maven2 repository is now hosted on the Sonatype repository.

You can access all artifacts on http://oss.sonatype.org/content/groups/public

Checkout source code

You can access new repository here: http://andromda.svn.sourceforge.net/viewvc/andromda

svn checkout  https://svn.code.sf.net/p/andromda/svn/trunk andromda

Read Me
This directory is useful only in the context of the SVN module andromda.
If you want to build the entire andromda project then issue a 'svn checkout  https://svn.code.sf.net/p/andromda/svn/trunk andromda'
and it will contain this directory's contents.

1) Install the latest version of Maven 3.0.4 (http://maven.apache.org) and add two environment variables
2) Set M2_HOME to the install directory and add $M2_HOME/bin to your $PATH.
3) Set MAVEN_OPTS: "export MAVEN_OPTS=-XX:MaxPermSize=256m\ -Xmx512m"
4) cd to andromda-all/maven/maven-config, run 'mvn install'
5) cd to andromda-all/maven/model-archiver, run 'mvn install'
   (NOTE: these steps only need to be performed the first time you build with a fresh release version).
4) cd to andromda-all, type "mvn". This will build the entire distribution, which can be found in the
   directory: andromda-distribution/target
5) Or call "mvn -Pandromda-full" to build and install the entire distribution including all sources and javadocs.
6) Use "mvn deploy -Pandromda-full,server" to build and deploy everything to the sonatype repository
7) Use "mvn site -Pandromda-site" or "mvn site -Pandromda-site-lite" to build site-documentation.
You deploy it with "mvn site:deploy -Pandromda-site,local" or "mvn site:deploy -Pandromda-site,server".

Good luck!

The AndroMDA Team

maven-enforcer-plugin:1.1.1:enforce (enforce-__my_company_1__k)

修改一下配置文件pom.xml,把1.7.0_21也加进去。

IE debug

做web开发的朋友都清楚,js程序的调试是相当郁闷的,因为首先这种语言语法比较灵活,它是一种弱类型的脚本语言,很多错误是无法控制的,这些不谈,最痛苦的是没有什么好的调试工具,现在的情况比以前稍好,在Firefox下还有firebug,这的确是一个不错的js调试工具,但在IE下使用就很麻烦,而且效果很不好,鄙人一直苦于寻找一个很好的IE下的js调试工具,能够自动捕获错误,并定位位置和原因,没想到今天竟在无意中寻找到了这么个好工具,不敢私藏,共享出来,希望能为各位web开发者带来方便

这个工具的名字叫Companion.JS,请注意,这可不是一个js文件,而是一个名字,它是作为ie的插件来安装使用的,而且需要结合Microsoft Script Debugger使用,通过安装这个工具,但页面出现错误时会在左上角弹出一个小错误提示,点击会在IE下面显示出一个错误控制台,就如FF下的 firebug控制台一样。错误信息提示很详细。

如下是官网的一个错误提示示例图: 点击在新窗口中浏览此图片

官网地址:http://www.my-debugbar.com/wiki/html/CompanionJS/HomePage

具体使用方法为: 1、先下载Companion.JS安装文件,然后安装。 2、下载安装Microsoft Script Debugger,如果您的机器已经安装过了就可以免过这一步。 3、打开IE菜单“工具”--“Internet选项”--“高级”,找到“禁用脚本调试(Internet Explorer)”和“禁用脚本调试(在Internet Explorer之外)”,将两个选项前面的对钩都去掉,然后重启IE。 4、在Ie中输入:http://www.my-debugbar.com/wiki/html/uploads/CompanionJS/dummy.htm%EF%BC%8C%E7%84%B6%E5%90%8E%E7%82%B9%E5%87%BBclick me链接,如果左上角弹出一个小错误提示或下面控制台出现了错误信息提示,就说明您已经安装成功了。

提示:Microsoft Script Debugger下载可到MS官网(需要经过MS的操作系统正版验证):http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=E606E71F-BA7F-471E-A57D-F2216D81EC3D#filelist%E6%88%96%E5%88%B0baidu%E9%87%8C%E8%BE%93%E5%85%A5%E2%80%9CMicrosoft Script Debugger 下载”寻找一下。

AppEngine

Getting started

Here’s how to get rolling:

  1. Install the gems

    $ sudo gem install google-appengine

  2. Assign an app identifier

    Simply create an application at appspot.com, we'll refer to that as my-app in this document.

  3. Generate your rails app

    $ rails my-app; cd my-app;

  4. Generate a rackup file

    In the same folder, save this as config.ru.

require 'appengine-rack'
AppEngine::Rack.configure_app(
  :application => 'my-app',
  :version => 1 )

%w{R db/ doc/ log/ script/ test/ tmp/}.each do |x|
  AppEngine::Rack.app.resource_files.exclude "/#{x}**"
end
ENV['RAILS_ENV'] = AppEngine::Rack.environment
require 'config/environment'

run ActionController::Dispatcher.new
  1. Check gem sources for datamapper

    $ gem sources

    Only when missing, add it like this... $ sudo gem source -a http://gems.datamapper.org

  2. Install gems into your app

    $ appcfg.rb gem install rails \ dm-appengine rails_datamapper

  3. Generate a model

    $ ./script/generate dm_model book title:string summary:text image_url:string available:boolean pages:integer -f --skip-timestamps --skip-migration

  4. Modify the Rails Initializer

    Add the following to your config/environment.rb.

# Set DataMapper to use dm-appengine adapter
require 'dm-core'
DataMapper.setup(:default, "appengine://auto")

# Set Logger from appengine-apis, all environments
require 'appengine-apis/logger'
config.logger = AppEngine::Logger.new

# Skip frameworks you're not going to use.
config.frameworks -= [ :active_record ]
  1. Run your app locally

    $ dev_appserver.rb .

  2. Open up the console

    $ appcfg.rb run -S irb > require 'config/environment'

  3. Deploy to App Engine

    $ appcfg.rb update .

Create a module

Popup menu

pattern wizard

Main class : ActionOpenPatternWizard

CoreFactory can create class and association

Installation

Creating a Custom Stereotype

Just like create a attribute.

5.12.1. The TargetManager

Located in org.argouml.ui.targetmanager.

The purpose of the targetmanager is to have a central spot to manage the list of current targets.

The target of ArgoUML is the element currently selected by the user. This can either be a UML element (an Interface or a Class for example) but it can also be a diagram or anything that is shown on a diagram.

There can be multiple targets in case someone selected multiple items in the explorer or on the diagram. This can be done by shift-clicking or Ctrl-clicking items, or by drawing a box on the diagram around the items to select.

In case multiple targets are selected, the target manager will add each target to the beginning of the list of targets. This way, the first item of the list is the last selected item. Most functions in ArgoUML work on all selected items. However, a few (intentionally) only work on one target, such as the properties panels.

Thanks to the architecture of ArgoUML of Modelelements and Figs, one rule has been decided upon: The list of targets shall not contain any Fig that has an owner. Instead, the owner is enlisted.

The TargetManager is also the manager of the history of targets. Every time the user (or the program) selects a new target, this is recorded in the history. Via navigateBack and navigateForward, the user can browse through the history just like in an ordinary internet browser.

Via an event mechanism this manager makes sure that all objects interested in knowing whether the selection changed are notified.

The TargetManager does not depend on the org.argouml.ui package, nor any of its sub-packages. Hence, it can be used by all of these to modify the target, or get it.

In a discussion on the dev list, it has been decided that the TargetManager is GUI state, and hence shall be a part of the GUI subsystem, and should not be used anywhere outside the GUI subsystem. However, currently the TargetManager is used in other subsystems, e.g. the Project. Hence, this needs refactoring.

5.1.2. Factories

5.1.2.1. Create and Build

The factories contain in most cases a create method for each model element. Example: createClass resides in CoreFactory-interface.

Besides that, there are several build methods to build classes. The build methods have a signature like public Object buildMODELELEMENTNAME(params);.

Each build method is intended to follow the wellformedness rules as defined in the UML spec. The reason for having extra build methods, is that the model repository does not enforce the wellformedness rules even though, in some cases, non-well-formed UML can lead to non-well-formed XMI which leads to saving/loading issues and all kinds of illegal states of ArgoUML.

If you want to create an element you shall use the build or create methods in the factories. You are strongly advised to use a build method or, if there is none that suits your needs, to write a new one reusing the already existing build methods and utility methods in the helpers. The reason for this is that the event listeners for the newly created model element are setup correctly.

5.1.2.2. Copy and DoCopy

The factories also contain methods that deal with copying modelelements. They are not supposed to be called directly from outside the model-subsystem, but only from the CopyHelper-implementation. The CopyHelper has one method that copies any modelelement into a new "location" (mostly a namespace). This method determines the type of element to copy, and then dispatches the call to the appropriate method of a Factory that is named in a similar way to copyClass.

The responsibility of the copyModelElement method is to create the new element (with createModelElement) and set the containment. Then, if necessary, sub-elements are to be created. E.g. the CoreFactoryMDRImpl. copyEnumeration method also creates EnumerationLiterals, with the createEnumerationLiteral method.

Then a next method is called to copy all the attributes from the old element to the newly created one: doCopyModelElement. This type of method shall only set attributes and lay associations, but not create any more elements.

The implementation of these copy related methods is far from complete. Only the CoreFactory already has the most important functions.

5.1.2.3. Multi-threading

Question: Am I allowed to call the factories from any thread? Answer: The current checks are not written to allow for multiple threads so don't!

5.1.3. Helpers

The helpers contain all utility methods for manipulating model elements. For example, they contain methods to get all model elements of a certain class out of the model (see getAllModelelementsOfKind in ModelManagementHelper).

To find a utility method you need to know where it is. As a rule of thumb, a utility method for some model element is defined in the helper that corresponds with the section in the UML specification. For example, all utility methods for manipulating classes are defined in CoreHelper.

There are a few exceptions to this rule, mainly if the utility method deals with two model elements that correspond to different sections in the UML specification. Then you have to look in both corresponding helpers and you will probably find what you are searching for.

Question: Am I allowed to call the helpers from any thread? Answer: The current checks are not written to allow for multiple threads so don't!

Setup JBoss

Start jboss

The following cmd will allow accessing jboss from remote machine.

./run.sh -b 0.0.0.0

The andromda's default setting is for HsqlDB, so we need not install another database. We only need download the JBoss http://www.jboss.org Edit the Hsqldb configure file located at

Installation

  • run install.sh jboss to install jboss
  • Set JBOSS_HOME variable : sudo gedit /etc/environment
  • Copy ../etc/hsqldb-ds.xml to %JBoss_Home%\server\default\deploy\hsqldb-ds.xml
  • run the follow command to uninstall jboss.

This line will delete all files copied by the JEMS Installer:

#+BEGIN_SRC java -jar $JBOSS_HOME/Uninstaller/uninstaller.jar -c#+END_SRC

This line will delete the whole $JBOSS_HOME folder includeing all log files, deployed applications and anything else inside it:

#+BEGIN_SRC java -jar $JBOSS_HOME/Uninstaller/uninstaller.jar -c -f#+END_SRC

Date

org.apache.axis2.databinding.typemapping.SimpleTypeMapper.makeCalenda r(SimpleTypeMapper.java:318)

Transaction

http://galaxy.andromda.org/forum/viewtopic.php?t=2438

Jippiee, i found the solution and it is very elegant. If anybody have a similar Situation like mine (want to do a large amount of work on the backend and wants to have control about transaction boundaries) ... here is the HowTo:

1.) Make sure to have enabled Spring transactions when ejb enabled in your andromda.xml: Code:

* Date 

org.apache.axis2.databinding.typemapping.SimpleTypeMapper.makeCalenda r(SimpleTypeMapper.java:318)

* Transaction 

http://galaxy.andromda.org/forum/viewtopic.php?t=2438

Jippiee, i found the solution and it is very elegant. If anybody have a similar Situation like mine (want to do a large amount of work on the backend and wants to have control about transaction boundaries) ... here is the HowTo:

1.) Make sure to have enabled Spring transactions when ejb enabled in your andromda.xml:
Code:

#+BEGIN_SRC
<property name="enableSpringTransactionsWhenEjbsEnabled">true</property>

Notice that the defaultvalue of this namespace property is true, so you can omit this property.

2.) Use the following tagged values on the method(s) you want to have encapsuled in own transaction:

@andromda.ejb.transaction.type = RequiresNew
@andromda.spring.transaction.type = PROPAGATION_REQUIRES_NEW

3.) Call the inner method by getting a Service Object from the generated ServiceLocator and call the method on this Service Object

example:

Code:

// outer method which is doing the whole import fo thowsands of data records
protected NahImportStats handleImportAll(ImportParam params) throws Exception
    {
        ImportStats stats = new ImportStats();
        initializeStats(stats);

        // first get the records to process...large list
        List data = this.getImportDao().executeQuery(query_selectData);

        // process each data record in the large list for it's own
        // get a new reference of the Service class... this can be the same or
        // anothe service class as the current one
        ImportService srv = ServiceLocator.instance().getImportService();

        for(Iterator i = nahEinsaetze.iterator(); iCnt < 30 && i.hasNext();)
        {
            Map colAtts = (Map)i.next();
            try{
                boolean ret = srv.importOneRecord(colAtts);
                stats.setAnzOk(stats.getAnzOk() + 1);
                }
            catch(Exception e){
                stats.setAnzNok(stats.getAnzNok() + 1);
                }         
            stats.setAnzVerarbeitet(stats.getAnzVerarbeitet() + 1);
            }
        return stats;
    }

// inner method which is called to do the import of each data record
// entering the method a new transaction is created
// leaving the method regularly hibernate session is flushing and the transaction is committed
// leaving the method with an exception a rollback is performed
protected boolean handleImportOneRecord(final Map colAtts)
   {
        .... bla bla....
        ....do the importing stuff ....
        ... including create, remove, update your data in the database ...
        ... do NOT add any transactional stuff like flush hibernate session,....

        ... if you want to get the work in this method rolled back throw a exception...

        return true;
   }

LG Michael

Developing a Cartridge

Steps To Building Your Own Cartridge

  1. Write your andromda-cartridge.xml file.

Cartridge Descriptor

Each cartridge descriptor must comply with the following XSD Schema .

Writing templates for your cartridges

AndroMDA currently comes with multiple cartridges (i.e. BPM4Struts, Hibernate, EJB, etc.) if these cartridge don't fit your needs, you'll need to write your own and thats where understanding how to write cartridges comes into play.

The template scripting language

Apache's Velocity is the default Template Engine of AndroMDA, and for that we use the Velocity Template Language (VTL). You can find a reference of this language here .

The scripting object model

Different from AndroMDA 2.x, AndroMDA 3.x no longer places any model elements in a template context. You define the names of elements to make available to the template in your cartridge's andromda-cartridge.xml, like so:

<template
path="templates/MetafacadeLogic.vsl"
outputPattern="$generatedFile"
outlet="facade-logics"
overwrite="true">
    <modelElements variable= "metafacade">
        <modelElement stereotype="metafacade"/>
    </modelElements>
</template>

MDA Introduction

Mvn

Introduction

Maven, a Yiddish word meaning accumulator of knowledge , was originally started as an attempt to simplify the build processes in the Jakarta Turbine project. There were several projects each with their own Ant build files that were all slightly different and JARs were checked into CVS. We wanted a standard way to build the projects, a clear definition of what the project consisted of, an easy way to publish project information and a way to share JARs across several projects.

The result is a tool that can now be used for building and managing any Java-based project. We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project.

Maven's Objectives

Maven's primary goal is to allow a developer to comprehend the complete state of a development effort in the shortest period of time. In order to attain this goal there are several areas of concern that Maven attempts to deal with:

  • Making the build process easy
  • Providing a uniform build system
  • Providing quality project information
  • Providing guidelines for best practices development
  • Allowing transparent migration to new features

http://maven.apache.org/

Velocity

http://velocity.apache.org/

Velocity is a simple yet powerful Java-based template engine that renders data from plain Java objects to text, xml, email, SQL, Post Script, HTML etc. The template syntax and rendering engine are both easy to understand and quick to learn and implement.

----------------------------------------------------------------------------------
--
--  Table Name:     ${table.getSchema()}.${table.getName()}
--  File Name:      ${table.getName()}.SQL
--  Author:         TODO
--  Date:
--
--  Abstract:
--
--
--  MAINTENANCE LOG
--  who  date        comment
--  ---  --------    ---------------------------------------------------------------
--  TODO             Initial Version
-----------------------------------------------------------------------------------
DROP TABLE ${table.getSchema()}.${table.getName()}
@

CREATE TABLE ${table.getSchema()}.${table.getName()}
(

#foreach($col in ${table.getColumns()})
    , ${col.getColumnDef()}
#end

)
    IN ${table.getSchema()}_DATA_01
    INDEX IN ${table.getSchema()}_INDX_01
@
--Primary Key
ALTER TABLE ${table.getSchema()}.${table.getName()}
    ADD     CONSTRAINT ${table.getName()}_PK
    PRIMARY KEY (
#foreach($col in $table.getCollumn())
    $col.getName(),
#end

    )
@

--Indexes
CREATE INDEX ${table.getSchema()}.${table.getName()}_I1
    ON ${table.getSchema()}.${table.getName()}(
#foreach($col in $table.getCollumn())
    $col.getName(),
#end
    )
@


-- Access privs
GRANT SELECT  ON ${table.getSchema()}.${table.getName()} TO GROUP WEB_GRP
@

Difference between MDA and DSL

Profile

I did some experiment with profiles in argouml 0.25.5, I referenced profiles in andromda by adding these lines in andromda.xml :

Code:

<repositories>
  <repository name="netBeansMDR">
    <models>
      <model>
        <uri>${model.uri}</uri>
        <moduleSearchLocations>
          <location patterns="**/*.xml.zip">${settings.localRepository}/org/andromda/profiles/uml14</location>
          <location patterns="**/*.xmi">${project.basedir}/#+BEGIN_SRC >
        </moduleSearchLocations>
      </model>
    </models>
  </repository>
</repositories>

Create Project

Generate

mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.3:generate


Please choose the type of application to generate [richclient, j2ee]
j2ee

Please enter the location in which your new application will be created (i.e. f:/java/development): 
/home/will/ideas/logistics/3.3

Please enter your first and last name (i.e. Chad Brandon): 
Will Chang

Which kind of modeling tool will you use? [uml1.4, uml2, emf-uml2]: 
uml1.4

Please enter the name of your J2EE project (i.e. Animal Quiz): 
New Logistics

Please enter an id for your J2EE project (i.e. animalquiz): 
logistics

Please enter a version for your project (i.e. 1.0-SNAPSHOT): 
0.2

Please enter the root package name for your J2EE project (i.e. org.andromda.samples.animalquiz): 
com.logistics

Would you like an EAR or standalone WAR? [ear, war]: 
ear

Please enter the type of transactional/persistence cartridge to use (enter 'none' if you don't want to use one) [hibernate, ejb, ejb3, spring, none]: 
ejb3

Please enter the database backend for the persistence layer [hypersonic, mysql, oracle, db2, informix, mssql, pointbase, postgres, sybase, sabdb, progress, derby]: 
hypersonic

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]: 
no

Will your project have a web user interface? [yes, no]: 
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]: 
struts

Would you like to be able to expose your services as web services? [yes, no]: 
yes

Would you like to use the JSR181 (webservice defined by annotations) EJB3 cartridge specific implementation? [yes, no]: 
yes

compare mda folder to find what need to be updated or copy

Copy core #+BEGIN_SRC

Mvn

Setup local repository

http://archiva.apache.org/docs/1.2.2/quick-start.html

http://blog.csdn.net/calvinxiu/archive/2007/07/28/1713323.aspx

http://www.jroller.com/sjivan/entry/using_maven_proxy_to_setup

Mirror : http://public.www.planetmirror.com/pub/sf/a/ar/artifactory/?sort=date&order=asc

create JavaEE with maven 2. http://maven.apache.org/plugins/maven-archetype-plugin/examples/j2ee-simple.html

http://mojo.codehaus.org/was6-maven-plugin/examples/installing-ears.html

http://www.mvnrepository.com/artifact/org.apache.velocity/velocity

Introduction to m2eclipse

Setting up a Maven repository

http://maven.apache.org/

http://maven.apache.org/guides/getting-started/index.html

        <dependency>
            <groupId>${pom.groupId}</groupId>
            <artifactId>quoteBase</artifactId>
            <version>${pom.version}</version>
            <scope>provided</scope>
        </dependency>

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>1.5</version>
<scope>compile</scope>
</dependency> 





    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	<dependency>

WAS 6

Maven 2 and WebSphere - automated build and deployment of J2EE applications After long search on different solutions on automated building and deployment of J2EE applications with maven that can work for WebSphere few posts were found. Some of them (big thanks to Peter Pilgrim) cover ways to build EJB modules that could be 'understood' by websphere (that is build websphere specific stubs and skeletons). Some posts show how to configure maven (including maven-eclipse-plugin) so that maven could work with RAD-6 and vice versa. All we have to do is put it all together, automate deployment of EAR (remember cargo plugin doesn't support websphere yet) to websphere and hook functional tests (using selenium) into the integration test phase. So the project consists of an ejb, war, ear, functional testing and a parent modules, like this:

parent_project
             |-ejb_module
             |
             |-war_module
             |
             |-ear_module
             |
             |-test_module

Looks like a complete set? Let's go through all the modules.

The EJB module.

The general problem is as it is well known the WebSphere requires generated stubs and skeletons packaged in ejb jar before the deployment which maven-ejb-plugin can't do. But IBM does offer java api to generate them via ant tasks. All we need to do is to 'silently' generate the server-specific files with ant tasks and repackage the ejb jar as a part of maven build cycle (usually generated by RAD during deployment in the IDE). In short this is how the pom may look like:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>your_group</ins></groupId>
  <artifactId>ejb_module</artifactId>
  <packaging>ejb</packaging>
  <name>ejb_module</name>
  <parent>
        <groupId>your_group</groupId>
        <artifactId>parent_project</artifactId>
        <version>0.1-SNAPSHOT</version>
  </parent>

  <dependencies>
        ...
        Your dependencies
        ...
        <dependency>
            <!-- provided by the container -->
            <groupId>websphere</groupId>
            <artifactId>j2ee</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ivjejb35</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>webservices</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>webservices</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ejbcontainer</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ejbcontainerImpl</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ecutils</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ras</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>ejbportable</artifactId>
            <version>6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- websphere specific dependency, available in own repository -->
            <groupId>websphere</groupId>
            <artifactId>utils</artifactId>
            <version>6</version>
        </dependency>
  </dependencies>

  <build>

        <finalName>${project.artifactId}</finalName>

        <!-- RAD-default source tree -->
        <sourceDirectory>ejbModule</sourceDirectory>
        <resources>
            <resource>
                <directory>ejbModule</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                    <exclude>**/CVS/**</exclude>
                </excludes>
            </resource>
        </resources>


    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ejb-plugin</artifactId>
            <configuration>
                <ejbVersion>2.1</ejbVersion>
                <generateClient>true</generateClient>
               <clientExcludes>
                  <clientExclude>**/ejbserver/*EJB.class</clientExclude>
               </clientExcludes>
                <archive>
                    <manifest>
                         <!-- generate manifest file properly -->
                        <addClasspath>true</addClasspath>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

        <plugin>
            <!-- Configuration of RAD specific JRE containers -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <configuration>
                <classpathContainers>
                    <!-- org.eclipse.__my_company_1__t.launching.JRE_CONTAINER is included by default, add a j2ee container here -->
                    <classpathContainer>com.ibm.wtp.server.java.core.container/com.ibm.ws.ast.st.runtime.core.runtimeTarget.v60/was.base.v6</classpathContainer>
                </classpathContainers>
            </configuration>
        </plugin>

        <!-- Maven Ant run plugin to run ejb-deploy automatically to simulate websphere's generation of stubs and skeletons -->
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>verify</phase>
                    <configuration>
                        <tasks>
                            <echo>was6.home: ${was6.home}</echo>

                            <!-- Default path to use for WAS test version (inside RAD), override this with -D parameter if needed -->
                            <property name="was6.home"
                                value="c:/Program Files/IBM/Rational/SDP/6.0/runtimes/base_v6" />

                            <ant antfile="ejbdeploy.xml" inheritRefs="true" inheritAll="true">
                                <property name="project.name" value="${project.name}"/>
                                <property name="project.artifactId" value="${project.artifactId}"/>
                                <property name="project.groupId" value="${project.groupId}"/>
                                <property name="project.version" value="${project.version}"/>
                                <property name="project.packaging" value="${project.packaging}"/>
                                <property name="project.description" value="${project.description}"/>
                                <property name="project.parent.name" value="${project.parent.name}"/>
                                <property name="project.parent.artifactId" value="${project.parent.artifactId}"/>
                                <property name="project.parent.groupId" value="${project.parent.groupId}"/>
                                <property name="project.parent.version" value="${project.parent.version}"/>
                                <property name="project.build.directory" value="${project.build.directory}"/>

                                       <!--
                                            This is to enable to override the was6.home by providing -Dwas6.home=<WAS home dir>.
                                            Use this to override the default path for the development environment (such as if you use standalone server
                                            and it has a different location than in the called ant file)
                                        -->
                                <property name="was6.home" value="${was6.home}"/>
                            </ant>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

  </build>

</project>

This pom is self explanatory for the most part (and I've tried to put some comments there as well). Text in bold is to be noticed, I will just stop on most important parts:

  • The header (down to dependencies) is pretty much clear I think, no magic here...
  • Dependencies. The dependencies I've put there is what I had to find out to resolve some vendor specific dependencies (which the project unfortunately already had). If your project already happened to have some WebSphere-specific dependencies that you would most likely need to define them too... I would recommend setting up an enterprise repository (for example Artifactory) as you won't find most of those those jar's on open source repositories (those jars can be found at websphere location, mostly under lib directory). Another recommendation is to start from no websphere dependencies in the list and start adding them only if you start having compile errors due to classes not being resolved. The reason behind adding those besides specifying the classpathContainer is that classpathContainer doesn't help when you compile under maven but only adds a classpath container entry in your .classpath file for compiling in RAD (we use RAD 6).
  • The next one is <finalName>${project.artifactId}</finalName>. The reason behind this is because module names in the vendor-specific deployment descriptors are based on RAD project names which means that having your project names having 0.1-SNAPSHOT (or whatever version you have) appended at the end is not very handy (you wont be able to release that easily). So we override the artifact name instead...
  • maven-ejb-plugin is there mostly to generate ejb jar manifest file properly (and to filter stuff for ejb the generated client).
  • maven-eclipse-plugin is configured to generate J2EE container in the .classpath which is needed for hot-deployment and compiling J2EE projects in RAD (for compiling in maven we have dependencies as described above).
  • And finally maven-antrun-plugin which is configured to kick in at verify phase which executes right before install phase. The maven-antrun-plugin is capable of executing ant scripts from maven at a specified time. To keep things a bit more clean we just call an external ant file from here

The WEB module.

This one is much easier, although with RAD-6 there are some 'tips&tricks'.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>your_group</groupId>
  <artifactId>web_module</artifactId>
  <packaging>war</packaging>
  <name>web_module</name>

      <parent>
        <groupId>your_group</groupId>
        <artifactId>parent_project</artifactId>
        <version>0.1-SNAPSHOT</version>
    </parent>

    <dependencies>
        ...
            Your dependencies
            ...
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>

        <!-- RAD-default source tree -->
        <sourceDirectory>${basedir}/JavaSource</sourceDirectory>

        <!--
            customizng resources location so that only needed files are archived in jar files
        -->
        <resources>
            <resource>
                <directory>${basedir}/JavaSource</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                    <exclude>**/*.class</exclude>
                </excludes>
            </resource>
        </resources>

            <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <warSourceDirectory>${basedir}/#+BEGIN_SRC >
                </configuration>
            </plugin>
        <!--
            customizing classes folder for RAD to pick it classes for hot deployment of exploded archive up - doesn't work with the default one (target)
        -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <configuration>
                    <buildOutputDirectory>${basedir}/#+BEGIN_SRC >
                    <!-- Customizing context root if needed -->
                    <warContextRoot>your_context_root</warContextRoot>
                    <additionalBuildcommands>
                        <!-- Needed by RAD in a typical web project -->
                        <buildcommand>com.ibm.etools.ctc.serviceprojectbuilder</buildcommand>
                    </additionalBuildcommands>
                    <!-- Configuration of RAD specific JRE containers -->
                    <classpathContainers>
                        <classpathContainer>com.ibm.wtp.server.java.core.container/com.ibm.ws.ast.st.runtime.core.runtimeTarget.v60/was.base.v6</classpathContainer>
                    </classpathContainers>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Let's go through it piece-by-piece... The beginning is pretty much standard for any web module. Don't forget to specify dependencies that are provided by the container in the same way as it is done in the ejb module, also don't forget to use excludes (and there are lots of exclusions for websphere!) or disable transitive dependencies alltogether. The next interesting part is:

<finalName>${project.artifactId}</finalName>

Which is needed in order to keep consistency between the maven-generated artifacts and RAD-generated vendor specific deployment desciptors.

The following piece:

is there to (still) allow to use default RAD source tree (however if you can afford moving whole source tree in your project or creating it from scratch I'd advice to use the maven default settings and not to use this one).

If we 'fall' for the above we would probably want to use the resource folder in 'RAD' way (that source with the resource files together):

#+BEGIN_SRC
            <!--
                customizing resources location so that only needed files are archived in jar files
            -->
            <resources>
                <resource>
                    <directory>${basedir}/JavaSource</directory>
                    <excludes>
                        <exclude>**/*.java</exclude>
                        <exclude>**/*.class</exclude>
                    </excludes>
                </resource>
            </resources>

Source and compiled classes are excluded so they don't get in the resulting .war file.

For the current version of maven (2.0.7 at the time of writing) the webapp root dir should match the default one of maven (${basedir}/#+BEGIN_SRC :

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <warSourceDirectory>${basedir}/#+BEGIN_SRC >
    </configuration>
</plugin>

Keep in mind it needs to be in 'sync' with <buildOutputDirectory>...</buildOutputDirectory> (or better yet - make it a property in order not to repeat yourself - DRY). And here we go:

<!--
    customizing classes folder for RAD to pick it classes for hot deployment of exploded archive up - doesn't work with the default one (target)
-->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>
            <buildOutputDirectory>${basedir}/#+BEGIN_SRC >
            <!-- Customizing context root if needed -->
            <warContextRoot>your_context_root</warContextRoot>
            <additionalBuildcommands>
                <!-- Needed by RAD in a typical web project -->
                <buildcommand>com.ibm.etools.ctc.serviceprojectbuilder</buildcommand>
            </additionalBuildcommands>
            <!-- Configuration of RAD specific JRE containers -->
            <classpathContainers>
                <classpathContainer>com.ibm.wtp.server.java.core.container/com.ibm.ws.ast.st.runtime.core.runtimeTarget.v60/was.base.v6</classpathContainer>
            </classpathContainers>
        </configuration>
    </plugin>

Here, buildOutputDirectory points at the same tree branch as the warSourceDirectory. warContextRoot is here just in case you want to customize the context root. com.ibm.etools.ctc.serviceprojectbuilder in additionalBuildcommands is needed because RAD usually generates it in .project file for eclipse for web-enabled projects. And of course the <classpathContainer/> which generates a reference required libraries for work in RAD (although you wouldn't need it if you use the enterprise repository with the vendor specific dependencies - just like in case with the ejb module).

This was the WEB project.

The EAR module.

There is really nothing special about it except this little configuration:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <configuration>
                <modules> <!-- Configuring names of artifacts in EAR -->
                    <webModule>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>web_module</artifactId>
                        <contextRoot>/your_context_root</contextRoot>
                        <bundleFileName>web_module.war</bundleFileName>
                    </webModule>
                    <ejbModule>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>ejb_module</artifactId>
                        <bundleFileName>ejb_module.jar</bundleFileName>
                    </ejbModule>
                </modules>
                <earSourceDirectory>${basedir}</earSourceDirectory>
                <earSourceIncludes>
                    **/ibmconfig/**
                </earSourceIncludes>
                <earSourceExcludes>**/target/**</earSourceExcludes>
            </configuration>
        </plugin>
    </plugins>
</build>

Here we have configuration of the application.xml where we have hardcoded (not nice but have to...) names of modules and the resulting artifacts that are packaged in the resulting ear (remember we have to have the same artifact names as the ones hardcoded in the IBM-specific deployment descriptors). And then there is some extra configuration telling to include the vendor specific deployment descriptors (we would need to create them in RAD) and extra configuration not to include the target directory in the resulting EAR.

Functional tests module

Functional test module (a separate maven module) is responsible for automated deployment to websphere and running the functional tests on the deployed application by using selenium).

In general, enabling fully automated integration tests for a j2ee application under websphere in this case consists of two parts: enabling selenium (a lot of info on this can be found here) and automated deployment of the application EAR to WAS before the selenium tests kick-in. Because we don't have a cargo plug-in for WAS-6 ready yet we use the ant scripts from websphere and plug them into the maven build lifecycle.

In short, running selenium tests and automated deployment of the application EAR can be done in the following steps:

  1. Define selenium repository (or have your enterprise repository take care of that)
  2. Define dependencies to be able to run selenium
  3. Automatically start selenium server just before the integration-test phase
  4. Force Surefire plugin to run in integration-test phase and not in test phase (this is a dedicated integration test module and doesn't need to run the test phase).
  5. Prepare EAR for the deployment script
  6. Call websphere deployment scripts in pre-integration test phase to deploy the EAR we prepared
  7. Run the tests (Surefire plug-in)
  8. Call websphere deployment scripts in post-integration test phase to undeploy the EAR (cleanup)

Let's go through all the steps:

  1. Define selenium repository (or have your enterprise repository take care of that). We can define it either in our pom (see below) or let artifactory take care of that:
<repositories>
    <repository>
        <id>openqa</id>
        <name>OpenQA Repository</name>
        <url>http://maven.openqa.org</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
</repositories>
  1. Define dependencies to be able to run selenium. This is also pretty straight forward:
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.openqa.selenium.client-drivers</groupId>
    <artifactId>selenium-java-client-driver</artifactId>
    <version>0.9.0</version>
</dependency>
<dependency>
    <groupId>org.openqa.selenium.server</groupId>
    <artifactId>selenium-server</artifactId>
    <version>0.9.0</version>
</dependency>

Here we have defined dependencies on JUnit in order to be run the selenium tests converted to JUnit, then we have client drivers to use the selenium client api in our JUnit tests and we have dependency on server which runs the selenium server to execute the tests.

  1. Automatically start selenium server just before the integration-test phase. This is defined in build/plugins section:
<!-- Start the Selenium server -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>selenium-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start-server</goal>
            </goals>
            <configuration>
                <background>true</background>
                <logOutput>true</logOutput>
                <multiWindow>true</multiWindow>
                <debug>true</debug>
            </configuration>
        </execution>
    </executions>
</plugin>

Notice that it starts in pre-integration phase, that is just before the integration phase starts.

  1. Force Surefire plugin to run in integration-test phase and not in test phase. This belongs to build/plugins section as well:
    <!--
Forcing test phase in integration-test phase
    -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <!-- Skip the normal tests, we'll run them in the integration-test phase -->
            <skip>true</skip>
        </configuration>
        <executions>
            <execution>
                <phase>integration-test</phase>
                <goals>
                    <goal>test</goal>
                </goals>
                <configuration>
        <skip>false</skip>
                </configuration>
            </execution>
        </executions>
    </plugin>

Notice the part with <skip>true</skip> - it tells maven to skip the test phase for this plugin otherwise test will fail because we haven't deployed the application yet. And then for the integration phase we enforce this plugin (also notice the part with <skip>false</skip> there)

  1. Prepare EAR for the deployment script. This is an interesting one... Because we don't have cargo plugin for WAS-6 that could seamlessly deploy the EAR to the server we need to prepare the EAR at a specific location so that 3rd party scripts could pickup the archive for deployment. This is how this can be done (also in the same build/plugins section):
<plugin>
    <!--
        This goal allows us to get the EAR from the repository for deployment and install it locally
    -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <!-- same group -->
                        <groupId>${project.groupId}</groupId>
                        <artifactId>your_artifact_name</artifactId>
                        <type>ear</type>
                        <overWrite>true</overWrite>
                        <destFileName>your_artifact_name.ear</destFileName>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${project.build.directory}</outputDirectory>
                <overWriteReleases>true</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>

The preparation of EAR for deployment is done by forcing the maven-dependency-plugin to copy resources (our EAR in this case) from local repository in package phase. Because the copying is done from the local repository we would need to use at least install (or later) phase in our parent module which would guarantee placement of our EAR in a local repository. The plugin takes the artifactId and type to identify the resource to copy, we also use the destFileName and outputDirectory to configure the final name and the location of the EAR. As a result of this configuration we get the archive we want to deploy in the target directory of this module.

  1. Call websphere deployment scripts in pre-integration test phase to deploy the EAR we prepared above to our websphere server (this can be both the websphere test environment integrated with the IDE or a dedicated server). Because we can't use cargo plugin we have to do something else - in this case we can use deployment scripts from websphere to deploy our artifacts. We configure both deploy and undeploy operations here. This is done with the help of maven antrun plugin by calling our ant scripts (they'll follow later):
<!-- Maven Ant run plugin to run deploy the EAR automatically to WebSphere-->
<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <!--
            Deployment to the server
        -->
        <execution>
            <id>deployment</id>
            <phase>pre-integration-test</phase>
            <configuration>
                <tasks>

                    <!-- default path to use for WAS test version (inside RAD), override this with -D parameter if needed -->
                    <property name="was6.home"
                        value="c:/Program Files/IBM/Rational/SDP/6.0/runtimes/base_v6" />
                    <ant antfile="eardeploy.xml" inheritRefs="true" inheritAll="true">
                        <property name="project.name" value="${project.name}"/>
                        <property name="project.artifactId" value="${final.artifact.name}"/>
                        <property name="project.groupId" value="${project.groupId}"/>
                        <property name="project.version" value="${project.version}"/>
                        <property name="project.packaging" value="${project.packaging}"/>
                        <property name="project.description" value="${project.description}"/>
                        <property name="project.parent.name" value="${project.parent.name}"/>
                        <property name="project.parent.artifactId" value="${project.parent.artifactId}"/>
                        <property name="project.parent.groupId" value="${project.parent.groupId}"/>
                        <property name="project.parent.version" value="${project.parent.version}"/>
                        <property name="project.build.directory" value="${project.build.directory}"/>

                        <!--
                            This is to enable to override the was6.home by providing -Dwas6.home=<WAS home dir>.
                            Use this to override the default path for the development environment (such as if you use standalone server
                            and it has a different location than in the called ant file)
                            -->
                        <property name="was6.home" value="${was6.home}"/>
                        <!--
                            Override the user.install.root by providing -Duser.install.root=<WAS profile dir>.
                            Use this to override the default path for the development environment (such as if you use standalone server
                            and it has a different location than in the called ant file)
                            -->
                        <property name="user.install.root" value="${user.install.root}"/>
                    </ant>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
        <!--
            Undeploy from the server after the tests are done
        -->
        <execution>
            <id>undeployment</id>
            <phase>post-integration-test</phase>
            <configuration>
                <tasks>
                        <ant antfile="eardeploy.xml" target="undeploy" inheritRefs="true" inheritAll="true">
                        <property name="project.name" value="${project.name}"/>
                        <property name="project.artifactId" value="${final.artifact.name}"/>
                        <property name="project.groupId" value="${project.groupId}"/>
                        <property name="project.version" value="${project.version}"/>
                        <property name="project.packaging" value="${project.packaging}"/>
                        <property name="project.description" value="${project.description}"/>
                        <property name="project.parent.name" value="${project.parent.name}"/>
                        <property name="project.parent.artifactId" value="${project.parent.artifactId}"/>
                        <property name="project.parent.groupId" value="${project.parent.groupId}"/>
                        <property name="project.parent.version" value="${project.parent.version}"/>
                        <property name="project.build.directory" value="${project.build.directory}"/>
                        </ant>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The deployment to the server is done in the pre-integration-test phase. Because maven runs goals in order that plugins are configured in build/plugins section we have the EAR file prepared for deployment properly. In the configuration section of antrun plugin we defined was6.homewhich points to default location of WAS for development environment but this can be easily overridden by using -Dwas6.home=<your WAS home> in the command line. We could put ant calls right here in the same place but it's better to separate ant from maven to get a 'cleaner' solution. Undeployment is performed by specifying second execution section and calling script that performs undeploy in post-integration-test phase which happens after the integration-test phase where our tests run. In this case it is the same script eardeploy.xml only a different target (undeploy). You can also notice we define properties such as project.artifactId inside the antcall target because antcall doesn't automatically passes all variables to the ant script from withiin the maven runtime environment (so we specify them explicitly).

And of course the ant script that performs the deployment and undeployment. It's quite big but fortunately it's not dependent on file system and thus can be easily reused across projects 'as is':

<?xml version="1.0"?>
<project name="was-deployment" default="deploy" basedir=".">

    <property file="deploy.properties" />

    <path id="was.classpath">
        <fileset dir="${was6.home}/lib">
            <include name="*.jar" />
            <include name="wsanttasks.jar" />
            <include name="webservices.jar" />
            <include name="wsprofile.jar" />
            <include name="j2ee.jar" />
            <include name="ffdc.jar" />
            <include name="wsdl4j.jar" />
            <include name="bootstrap.jar" />
            <include name="commons-logging-api.jar" />
            <include name="commons-discovery.jar" />
            <include name="ras.jar" />
            <include name="wsexception.jar" />
            <include name="emf.jar" />
            <include name="classloader.jar" />
        </fileset>
        <fileset dir="${was6.home}/java/jre/lib">
            <include name="xml.jar" />
            <include name="ibmorb.jar" />
            <include name="ibmorbapi.jar" />
        </fileset>
    </path>


    <target name="init-tasks">
        <taskdef name="wsInstallApp" classname="com.ibm.websphere.ant.tasks.InstallApplication">
        </taskdef>
        <taskdef name="wsUninstallApp" classname="com.ibm.websphere.ant.tasks.UninstallApplication">
        </taskdef>
        <taskdef name="wsStartApp" classname="com.ibm.websphere.ant.tasks.StartApplication">
        </taskdef>
    </target>

    <target name="ws-exec">
          <exec executable="${user.install.root}/bin/ws_ant.bat" failonerror="true">
            <arg value="-f"/>
            <arg value="eardeploy.xml"/> <!-- this is this own build file name but to be restarted with IBM implementation of ant -->
            <arg value="-Dwas6.home=${was6.home}"/>
            <arg value="${wasTarget}"/>
            <arg value="-Dear.path=${ear.path}"/>
            <arg value="-Dproject.artifactId=${project.artifactId}"/>
        </exec>
    </target>


    <target name="deploy" description="Deploys EARs to the WAS">
        <echo>
            FYI

            project.name=${project.name}
            project.artifactId=${project.artifactId}
            project.groupId=${project.groupId}
            project.version=${project.version}
            project.packaging=${project.packaging}
            project.description=${project.description}

            project.parent.name=${project.parent.name}
            project.parent.artifactId=${project.parent.artifactId}
            project.parent.groupId=${project.parent.groupId}
            project.parent.version=${project.parent.version}

            ear.path=${ear.path}
            was6.home=${was6.home}
        </echo>

        <antcall target="ws-exec">
              <param name="wasTarget" value="deploy-ear" />
        </antcall>

    </target>

    <target name="undeploy" description="Undeploys the application fromthe server">
        <antcall target="ws-exec">
              <param name="wasTarget" value="undeploy-ear" />
        </antcall>
    </target>


    <target name="deploy-ear" depends="init-tasks, undeploy-ear">
        <echo>Deploying ear ${ear.path} to websphere via ws_ant</echo>
        <echo>Host: ${host}, port: ${port}</echo>

        <wsInstallApp wasHome="${was6.home}"
            ear="${ear.path}"
            options="-usedefaultbindings -verbose true"
            conntype="SOAP"
            host="${host}"
            port="${port}"
            />

        <antcall target="start-app" />

    </target>

    <target name="start-app">
        <wsStartApp wasHome="${was6.home}"
            application="${project.artifactId}"
            conntype="SOAP"
            host="${host}"
            port="${port}"/>
    </target>

    <target name="undeploy-ear" depends="init-tasks" >
        <wsUninstallApp wasHome="${was6.home}"
            application="${project.artifactId}"
            conntype="SOAP"
            host="${host}"
            port="${port}"/>
    </target>
</project>

This ant script uses ant tasks wsInstallApp, wsUninstallApp and wsStartApp provided by websphere. They are all needed to deploy (wsInstallApp target) the application and start it wsStartApp (separate action in webpshere) and then to undeploy the application (wsUninstallApp target). To protect this script from often changes we have was.classpath which provides classpath for those targets and deploy.properties file provides properties that you're likely to customize per application (or environment). Then we have a 'strange' ws-exec target which basically runs the same script again but this time passes it through ${user.install.root}/bin/ws_ant.bat which is an own implementation of ant from IBM. We do this mostly because those ant tasks we described require a lot of system and environment variables setup. And since this is a proprietary solution of IBM it's easier to let those scripts to do the initialization job and then return to our deploy.xml. We also pass the required properties (as command line arguments) through this script which in this case are:

  • eardeploy.xml - the same script to run (in command line this is usually "-f <script name>")
  • -Dwas6.home=${was6.home} - passing the location of websphere home dir location as system variable (as you can see it's used all across the script)
  • ${wasTarget} - the next ant target in this script to run
  • -Dear.path=${ear.path} - path of the ear file for deployment
  • -Dproject.artifactId=${project.artifactId} - name of the application for undeployment (I recommend to configure EAR name as artifact name with '.ear' extension appended - for example artifactId.ear, you can also see across the scripts that we have final artifact name defined which also serves this purpose)

The rest is pretty straight forward, we have deploy target which calls IBM version of ant implementation which in turn calls deploy-ear which actually calls the corresponding ant task. The same is valid for undeploy target. With the exception that deploy-ear target includes call to start-app target which starts the application as soon as it is deployed (those operations are synchronous). In short for deployment we have the following workflow:

deploy target --> ws_ant (WAS environment initialization) --> deploy-ear --> start_ear

and for undeployment:

undeploy target --> ws_ant (WAS environment initialization) --> undeploy-ear

Another thing to notice is that deploy also includes call for undeployment - this is provided in case if integration tests failed (which cause all later maven phases including undeployment being aborted) so that next deployment operation cleans up before its own execution. In case if the application is not deployed the undeployment fails silently without aborting the whole workflow (unfortunately if deployment fails its also silent but then our integration test also will fail because there is no application to test :) ).

And finally we have deploy-ear, start-app and undeploy-ear which call websphere tasks directly. We also have host and port configured in deploy.properties file:

host=localhost

port=8880

One last side-note, if you want to have a source directory in generated RAD project when you run mvn eclipse:rad you woudl want to use packaging type jar (<packaging>jar</packaging>)

Parent module

This is the last module which serves as an orchestration assembly module for the whole application. It also defines a functional tests profile which allows developers to work on the application and build without invoking system integration tests (they can be slow depending on your application complexity). We can invoke the funstional test profile, for example, on our continuous integration server (continuum is used in this case). This a typical parent module with packaging type pom (<packaging>pom</packaging>). It has only two 'specific' for this whole task sections: the module and profile definition and compiler settings.

The module definition is pretty simple:

<modules>
    <module>ejb_module</module>
    <module>war_module</module>
    <module>ear_module</module>
</modules>
<!--
    Functional test, activation can be done by adding '-P functional-test' (no quotes) at the end of the command line e.g.:> mvn install -P functional-test
-->
<profiles>
    <profile>
        <id>functional-test</id>
        <activation>
            <property>
                <name>enableCiProfile</name>
                <value>true</value>
            </property>
        </activation>
        <modules>
            <module>test_module</module>
        </modules>
    </profile>
</profiles>

According to the configuration above the default execution of build wont include the building of functional (integration) tests module. If we want to include integration tests as part of our build we can append "-P functional-test" at the command line, e.g. mvn install -P functional-test. There are also other ways of triggering this profile.

And the last section of the parent module forces compiler to compile all java classes to java 1.4 compatible bytecode across all modules (because WAS-6 supports bytecode upto java 1.4):

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.4</source>
                <target>1.4</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Because all other modules declare this module as parent one they all use this setting so we don't have to specify it at every module that compiles java code.

Now, in order to generate RAD projects from our maven files we can use the following command:

mvn eclipse:rad

and maven eclipse plugin takes care of the rest. Now, to build the entire project we can invoke the following command:

mvn install -Duser.install.root="path to your WAS profile dir"

Where you can specify the path to your websphere profile dir which is needed to build stubs and sceletons for your EJBs (as specified in the EJB module section). And finally, if we want to have a complete build including the integration tests that also deploy the application to the server we can issue the following command:

mvn install -P functional-test -Duser.install.root="path to your WAS profile dir"

This line looks pretty long so we can put in a command line script.

If there are any questions or constructive comments you are welcome to send them in! :) Posted by Siarhei Dudzin at 3:41 PM 13 comments:

Anonymous said...

Maybe http://mojo.codehaus.org/was6-maven-plugin can be of use for you? March 16, 2008 4:37 PM Siarhei Dudzin said...

This definitely looks interesting! At the time of writing there were no plugins available. March 16, 2008 5:04 PM Anonymous said...

it is really a great article.although i got this article after i was done with maven with same approach. i was thinking to document it,but i dont need to do so. it is more than enough. he has done a gre8 work. just gre8888888888888888 May 8, 2008 10:37 AM Anonymous said...

Would you include the ejbDeploy.xml code as well, as this is missing from your post.

Thanx May 31, 2008 7:24 PM Siarhei Dudzin said...

It is not missing, it is just before the "Parent module" section :) June 1, 2008 1:48 PM netslow said...

Do you know is there any possibility to set automatic redeploy after server starts? Maybe there is an option to set auto redeploy after (for example) 60 seconds? July 3, 2008 6:33 AM Siarhei Dudzin said...

You could try Hot deployment and dynamic reloading July 3, 2008 10:28 AM subhas said...

I am very new in Maven world.I want to develop J2EE project(EJB,WEB) using RAD 6 and Maven.After generate the RAD related file when I import WebModule(in eclipse way , in eclipse works fine) into RAD I got some build error and it's not allowed to deploy because it's not part of valid j2ee project.So I tried to import Enterprise module and it's imported properly but war included into the EAR.So I can't change the code. Can any body give any clue how you are debug and fix in RAD of maven project.

Subhas July 15, 2008 2:14 PM Siarhei Dudzin said...

For rad use eclipse:rad and eclipse:rad-clean goals. Do not put WTP 2.0 property in maven-eclipse-plugin configuration. July 15, 2008 4:24 PM subhas said...

Thank you very much for quick reply.I used maven eclipse plugin for create RAD specific .project and others file.As you describe I put the following entry in my pom.xml

plugin groupId::org.apache.maven.plugins artifactId::maven-eclipse-plugin configuration: buildOutputDirectory :: ${basedir}/#+BEGIN_SRC

additionalBuildcommands buildcommand::com.ibm.etools.ctc.serviceprojectbuilder additionalBuildcommands

classpathContainers classpathContainer::com.ibm.wtp.server.java.core.container/com.ibm.ws.ast.st.runtime.core.runtimeTarget.v60/was.base.v6

classpathContainers configuration plugin

But after creating the project related file When I tried to import into the RAD 6 it's not build properly , I got some popuup with not build properly ..

Can you provide some details how you import this project(maven project) into RAD 6 workspace.I used import -> import from exting project -> select path -> FiNISH

After build fail when I try to deploy into Test Server it's gave message like not valid J2EE project. July 15, 2008 6:11 PM Siarhei Dudzin said...

This is exactly how I import the projects.

If you use web services I recommend to use default RAD directory layout (it can't always deal 'customized' source and web folders). July 18, 2008 4:05 PM Dev_Chennai said...

Hi, I want to install my project in Both WebSphere & Weblogic Servers.So I want to creat a server based maven build.Is it possible to create this.For example,If i want to build for WebSphere,I need ejbDeploy process & for Weblogic I don't need.Any one has any documents or ideas..? September 10, 2008 9:37 PM Dev_Chennai said...

Hi, I want to install my project in Both WebSphere & Weblogic Servers.So I want to creat a server based maven build.Is it possible to create this.For example,If i want to build for WebSphere,I need ejbDeploy process & for Weblogic I don't need.Any one has any documents or ideas September 10, 2008 9:38 PM

Post a Comment Newer Post Older Post

Ran mvn -Dmaven.test.skip will skip test, this will speed the install process.

remove xercer jars from ear file to avoid the cast exception.

Grails 1.1.1正式支持Google App Engine

Check box image

add new template

  1. update the file /home/will/newlogistics/mda/#+BEGIN_SRC
 <mapping>
     <from><![CDATA[<!-- cartridge-template merge-point -->]]></from>
     <to>
         <![CDATA[

<template
     path="templates/bpm4struts/pages/crud/dojo.jsp.vsl"
     outputPattern="{0}/{1}dojo.jsp"
     outlet="pages"
     overwrite="true">
     <modelElements variable="manageable">
         <modelElement>
             <type name="org.andromda.cartridges.bpm4struts.metafacades.StrutsManageableEntity"/>
         </modelElement>
     </modelElements>
 </template>
         ]]>
     </to>
 </mapping>
  1. create file: /home/will/newlogistics/mda/#+BEGIN_SRC

SCHEMA names in persistent tables

Install HsqlDB

Install a database The andromda's default setting is for HsqlDB, so we need not install another database. We only need download the JBoss http://www.jboss.org Edit the Hsqldb configure file located at %JBoss_Home%\server\default\deploy\hsqldb-ds.xml uncomment:

<connection-url>__my_company_1__bc:hsqldb:hsql://localhost:1701</connection-url>

comment : <#+BEGIN_SRC

uncomment

<mbean code="org.jboss.__my_company_1__bc.HypersonicDatabase"
    name="jboss:service=Hypersonic">
    <attribute name="Port">1701</attribute>
    <attribute name="Silent">true</attribute>
    <attribute name="Database">default</attribute>
    <attribute name="Trace">false</attribute>
    <attribute name="No_system_exit">true</attribute>
  </mbean>

and

<mbean code="org.jboss.__my_company_1__bc.HypersonicDatabase"
     name="jboss:service=Hypersonic,database=localDB">
     <attribute name="Database">localDB</attribute>
     <attribute name="InProcessMode">true</attribute>
   </mbean>

OK, HsqlDB is ready to use.

Customize web service

Using the following code to get the association.

<!--

## Generate the relation methods.
#foreach ($associationEnd in $service.associationEnds)
#set ($target = $associationEnd.otherEnd)
#if ($target.navigable)
    private $target.getterSetterTypeName $target.name;

    /**
     * Get the $target.name
$target.getDocumentation("     * ")
     */
    public $target.getterSetterTypeName ${target.getterName}()
    {
        return this.${target.name};
    }

## - always have as public, having read-only causes too many issues when attempting to
##   use in other cartridges
    /**
     * Sets the $target.name
     */
    public void ${target.setterName}($target.getterSetterTypeName $target.name)
    {
        this.${target.name} = ${target.name};
    }

#end
#end

-->

Javascript

* delete cookie

<input type="submit" />

<input type ="Button" name="clear" value="Clear Cookies" onclick="deleteAllCookies();"/>
<div id="cookieinfo">
Here.
</div>
</form>
<script>
function deleteAllCookies() {
   	delete_cookie();
	
	show_cookie();
}



function delete_cookie (  ){
  	document.cookie = "stCookie=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/;domain=ibm.com";
  	document.cookie = "wbac=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/;domain=ibm.com";
	document.cookie = "wbac1=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/;domain=ibm.com";
	document.cookie = "JSESSIONID=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/";
}



function show_cookie(){
	var cookies = document.cookie.split(";");
    var str=""
    for (var i = 0; i < cookies.length; i++) {
        var cookie = cookies[i];
        str+=cookie+"<br>"
    }
	document.getElementById('cookieinfo').innerHTML = str;
}

	show_cookie();
</script>


</body>

mydb2 online

http://docs.dojocampus.org/dojo/xhrPost?highlight=(dojo\.xhrPost)

function moreParamsToUrl(){
	var params = {};
	var moreParams = document.getElementById("moreparams");
	if((moreParams != null) && (moreParams.value!="")) {
		//alert(moreParams.value);
		var paramsArray = moreParams.value.split('&');
		for( var i=0; i<paramsArray.length; i++ ){
			var param = paramsArray[i].split('=');
			params[param[0]] = param[1];
		}
	}
	//alert(dojo.toJson(params));
	return params;
}

function loadTreeFromUrl(nodeItem){
			var url = nodeItem.url.toString();
			var xhrArgs = {
			url: url,
			sync : false,
			postData : dojo.toJson(moreParamsToUrl()),
			headers: {"Content-Type": "application/json"},
			handleAs: "text",
			preventCache : true,
			load: function(data){
				try{
				//alert(data);
				var treeNodeID = getRequestParam(url,'nodeID');
				var treeNodes = dojo.fromJson(data);
				if( !treeNodes.nodes.length ){
					treeNodes.nodes.push({id:'',desc:treeNodes.messages['No.Result.Msg'],loaded:true});
				}
				
				if( !treeNodeID.length ){
					var treeName = unescape(getRequestParam(url,'treeName'));
					if("ProdTypePartTree"==treeName){
						url += '&nodeID=0';
					}
					var items = handleNode(treeNodes.nodes,'0',url);		
					createTree(treeName,items);
					dojo.connect(tree, "_onExpandoClick", function(message){
							asyncLoadNodesData(message);
					});
					if(unescape(getRequestParam(addMoreParamsToUrl(url),'dataRetrievalType'))!='browse'){
						dojo.byId('switch_collapse_expand').style.display = "";
					}
					return;
				}
				var childItems = handleNode(treeNodes.nodes,nodeItem.nodeId,url);	
				//alert(dojo.toJson(childItems));
				for( var i in childItems ){
					tree.store.newItem(childItems[i],{parent: nodeItem, attribute:"children"});
				}
				expand_all(tree._itemNodeMap[tree.model.getIdentity(nodeItem)]);
				}catch(e){
					alert(e.message);
				}
			},
			error: function(error){
				tree.store.setValue(nodeItem, "loaded",false);
				alert(error);
			},
			handle : function(resultContent){
				tree._itemNodeMap[tree.model.getIdentity(nodeItem)].unmarkProcessing();
			}
		}
		var deferred = dojo.xhrPost(xhrArgs);
}

JavaScript判断浏览器类型及版本

<script type="text/javascript">
    var Sys = {};
    var ua = navigator.userAgent.toLowerCase();
    window.ActiveXObject ? Sys.ie = ua.match(/msie ([\d.]+)/)[1] :
    document.getBoxObjectFor ? Sys.firefox = ua.match(/firefox\/([\d.]+)/)[1] :
    window.MessageEvent && !document.getBoxObjectFor ? Sys.chrome = ua.match(/chrome\/([\d.]+)/)[1] :
    window.opera ? Sys.opera = ua.match(/opera.([\d.]+)/)[1] :
    window.openDatabase ? Sys.safari = ua.match(/version\/([\d.]+)/)[1] : 0;

    //以下进行测试
    if(Sys.ie) document.write('IE: '+Sys.ie);
    if(Sys.firefox) document.write('Firefox: '+Sys.firefox);
    if(Sys.chrome) document.write('Chrome: '+Sys.chrome);
    if(Sys.opera) document.write('Opera: '+Sys.opera);
    if(Sys.safari) document.write('Safari: '+Sys.safari);
</script>

Popup Calendar used in DSW

http://www.dynarch.com/static/jscalendar-1.0/simple-1.html

<p><b>Hidden field, display area.</b> Very much like the previous
examples,
but we now disable some dates (all weekends, that is, Saturdays and
Sundays).</p>

<form action="#" method="get" style="visibility: hidden;">
<input name="date" id="f_date_f" type="hidden">
</form>

<p>Your birthday:
   <span style="background-color: rgb(255, 255, 136); cursor:
default;" onmouseover="this.style.backgroundColor='#ff0';"
onmouseout="this.style.backgroundColor='#ff8';" id="show_f">Click to
open date selector</span>.</p>

<script type="text/javascript">
    Calendar.setup({
            inputField     :    "f_date_f",     // id of the input field
	            ifFormat       :    "%Y/%d/%m",     // format of
the input field (even if hidden, this format will be honored)
        displayArea    :    "show_f",       // ID of the span where
the date is to be shown
        daFormat       :    "%A, %B %d, %Y",// format of the displayed
date
        align          :    "Tl",           // alignment (defaults to
"Bl")
        dateStatusFunc :    function (date) { // disable weekend days
(Saturdays == 6 and Subdays == 0)
                              return (date.getDay() == 6 ||
date.getDay() == 0) ? true : false;
                            }
			        });
				</script>

Javascript debugger

Just started using Jash for debugging my JavaScript. It is a JavaScript shell that you can dynamically startup and directly execute JavaScript functions within another webpage. So when I am developing, I can try out new JavaScript or execute debug statements right in the page without having to edit server side code or reload. Very easy to use, zero install, very impressive tool.

REX

3)match 得到查询数组

var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /cat/gi;
var arrMactches = data.match(reCat)

for (var i=0;i < arrMactches.length ; i++)
{
     alert(arrMactches[i]);   //Cat  cat
}

Dojo

build

build.sh profile=standard action=release

in the jsp, include the dojo.js and mydojo.js in the release folder. Then you need not "require the dojo package"

Getting the Code

Download the newest released version of the Dojo Toolkit from: http://download.dojotoolkit.org/current-stable/

Manual

i18n

Internationalization (i18n) Encoding considerations

This is the sample /home/will/logic.war/demo/JavaScriptSOAPClient_demo/test_grid.html

dojo.query http://redesign.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.query

Internationalization (i18n) javascript partprice.js

Notes://D01DBL35/8525721300181EEE/477C010BD75EC87C85256A2D006A582E/52B949983525B8B3852575530024AEDE

There are two options to move the display text from js file to properties file :

Here is the reference for dojo.i18n http://www.dojotoolkit.org/book/book-dojo/part-1-life-dojo-dojo-and-dijit-application-examples/example-1-why-doesnt-anyone-fi-0.

Below is the instruction to update pratprice.js file.

To use dojo.i18n, we need create some "javascript properties" files.

The partpricemsg.js files(in the picture above) are "javascript properties" files. They are put in different folders according to the locale.

{

no_future_maint_start_date: "Start date of this part cannot be in the future.", earlier_than_current_date:"Start date may not be earlier than current date.Please update the start date."

}

Update partprice.js dojo.require("dojo.i18n"); dojo.registerModulePath("quote.web", "../../"); dojo.requireLocalization("quote.web","partpricemsg"); var i18nStr = dojo.i18n.getLocalization("quote.web", "partpricemsg");

....

function validateDates(isFTL,startDateYear,startDateMonth,startDateDay,endDateYear, endDateMonth,endDateDay, backDatingAllowed, isLicencePart, stdStartDate, stdEndDate, pastYearLimit, currentYear, currentMonth, currentDay) { //check whether start date/end date is earlier than today var today = getDate(currentYear, currentMonth, currentDay); var startDate = getDate(startDateYear, startDateMonth-1, startDateDay); var endDate = getDate(endDateYear, endDateMonth-1, endDateDay);

//special trade for licence part, because it's start date should never be in the future if(isLicencePart && (startDate > today)){ //alert("Start date of this part cannot be in the future."); alert(i18nStr["no_future_maint_start_date"]); return false; } Update JSPs files We need include the dojo.js file and set the value of locale. <script language="javascript" type="text/javascript" djConfig="parseOnLoad:true, isDebug: false, locale: 'en'"

#+BEGIN_SRC "> </script>

Below is the instruction to update pratprice.js file.

Rname partprice.js to partprice.jsp

In order to use jade tags, we need rname partprice.js to partprice.jsp. <%@ taglib uri="jadetags.tld" prefix="jade"%> / partprice.js

....

function validateDates(isFTL,startDateYear,startDateMonth,startDateDay,endDateYear, endDateMonth,endDateDay, backDatingAllowed, isLicencePart, stdStartDate, stdEndDate, pastYearLimit, currentYear, currentMonth, currentDay) { //check whether start date/end date is earlier than today var today = getDate(currentYear, currentMonth, currentDay); var startDate = getDate(startDateYear, startDateMonth-1, startDateDay); var endDate = getDate(endDateYear, endDateMonth-1, endDateDay);

//special trade for licence part, because it's start date should never be in the future if(isLicencePart && (startDate > today)){ alert("<jade:i18nContext key="no_future_maint_start_date" basename="appl.i18n.partprice" />"); return false; }

....

Update JSPs <script language="javascript" type="text/javascript" #+BEGIN_SRC >

  1. Discussion pros and cons

Options || Pros || Cons

  1. Using dojo.i18n | It is an elegant way. | Dojo is not bug free. Using dojo.i18n may introduce some bugs which we can

not fix. We need efforts to synchronizing "java properties" and "javascript properties".

  1. Using jade i18n tag | Use the same java properties. We are familiar with jade tags. | It is not an elegant way.

Dialog

EasyMDA 3.4

papyrus

Indigo (3.7)

http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/indigo

http://www.eclipse.org/downloads/

Papyrus Insallation

Follow the instructions below to install Papyrus.

Documentation is on the Papyrus site http://www.eclipse.org/modeling/mdt/papyrus Add the update site for Papyrus to Eclipse as specified in http://www.eclipse.org/modeling/mdt/papyrus/updates/index.php Install Papyrus from Eclipse by Help -> Install New Software... After generating the starter project with the EMF-UML2 modeling option. This creates the project .uml and profile.uml files in the mda\#+BEGIN_SRC . Import the starter .uml model into Papyrus to create a papyrus 'diagram', following the instructions at http://wiki.eclipse.org/Papyrus_User_Guide#Create_a_diagram_from_an_existing_uml_file Create a diagram from an existing uml file (New -> Initialize Papyrus Diagram).

Get started

  1. edit /etc/envirment to add m2_repo

    http://www.andromda.org/docs/andromda-documentation/getting-started-java/env-setup.html

  2. mvn archetype:create -DgroupId=testapp -DartifactId=testapp

    cd testapp

  3. Edit pom.xml in this directory to add the following content:
"></script>







Below is the instruction to update pratprice.js file.

Rname partprice.js to partprice.jsp

In order to use jade tags, we need rname partprice.js to partprice.jsp.
<%@ taglib uri="/jadetags.tld" prefix="jade"%>
// partprice.js

....

function validateDates(isFTL,startDateYear,startDateMonth,startDateDay,endDateYear,
                          endDateMonth,endDateDay, backDatingAllowed, isLicencePart,
                          stdStartDate, stdEndDate, pastYearLimit, currentYear, currentMonth, currentDay) {
 //check whether start date/end date is earlier than today
 var today = getDate(currentYear, currentMonth, currentDay);
 var startDate = getDate(startDateYear, startDateMonth-1, startDateDay);
 var endDate = getDate(endDateYear, endDateMonth-1, endDateDay);

 //special trade for licence part, because it's start date should never be in the future
 if(isLicencePart && (startDate > today)){
  alert("<jade:i18nContext key="no_future_maint_start_date" basename="appl.i18n.partprice" />");
      return false;
 }

....

Update JSPs
 <script language="javascript" type="text/javascript" #+BEGIN_SRC >




3) Discussion pros and cons

Options ||  Pros    || Cons
1) Using dojo.i18n |    It is an elegant way. |         Dojo is not bug free. Using dojo.i18n may introduce some bugs which we can
not fix.        We need efforts to synchronizing "java properties" and "javascript properties".
2) Using jade i18n tag |    Use the same java properties.   We are familiar with jade tags. |   It is not an elegant way.


** Dialog


* EasyMDA 3.4

**  papyrus

  Indigo (3.7)

 http://download.eclipse.org/modeling/mdt/papyrus/updates/releases/indigo

  http://www.eclipse.org/downloads/

  [[http://www.andromda.org/andromda-documentation/getting-started-java/resources/uml-tools/papyrus/install.html][Papyrus Insallation]]

Follow the instructions below to install Papyrus.

Documentation is on the Papyrus site http://www.eclipse.org/modeling/mdt/papyrus
Add the update site for Papyrus to Eclipse as specified in http://www.eclipse.org/modeling/mdt/papyrus/updates/index.php Install Papyrus from Eclipse by Help -> Install New Software...
After generating the starter project with the EMF-UML2 modeling option. This creates the project .uml and profile.uml files in the mda\#+BEGIN_SRC .
Import the starter .uml model into Papyrus to create a papyrus 'diagram', following the instructions at http://wiki.eclipse.org/Papyrus_User_Guide#Create_a_diagram_from_an_existing_uml_file Create a diagram from an existing uml file (New -> Initialize Papyrus Diagram).

** UML 2

 http://www.eclipse.org/modeling/mdt/downloads/?project=uml2

*** Install steps

  1. http://download.eclipse.org/e4/sdk/drops/R-4.1-201106201631/index.php
  2. Update manager
    - http://download.eclipse.org/modeling/mdt/updates/releases/
    - http://download.eclipse.org/modeling/emf/updates/releases/
    - http://download.eclipse.org/modeling/mdt/uml2tools/updates/interim/

** Get started

1) edit /etc/envirment to add m2_repo

  http://www.andromda.org/docs/andromda-documentation/getting-started-java/env-setup.html

2)  mvn archetype:create -DgroupId=testapp -DartifactId=testapp

    cd testapp

3) Edit pom.xml in this directory to add the following content: 

#+BEGIN_SRC

<repositories>
    <repository>
        <id>sonatype</id>
        <name>Sonatype Repository</name>
        <url>http://oss.sonatype.org/content/groups/public</url>
       <snapshots>
          <enabled>true</enabled>
       </snapshots>
    </repository>
    <repository>
        <id>jboss</id>
        <name>JBoss Repository</name>
        <url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
        <id>sonatype</id>
        <name>Sonatype Repository</name>
        <url>http://oss.sonatype.org/content/groups/public</url>
       <snapshots>
          <enabled>true</enabled>
       </snapshots>
    </pluginRepository>
  </pluginRepositories>
<build>
    <defaultGoal>compile</defaultGoal>
    <plugins>
        <plugin>
            <groupId>org.andromda.maven.plugins</groupId>
            <artifactId>andromdapp-maven-plugin</artifactId>
            <version>3.5-SNAPSHOT</version>
        </plugin>
    </plugins>
</build>
  1. mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.5-SNAPSHOT:generate
INFO  [AndroMDA] discovered andromdapp type --> 'j2ee'
INFO  [AndroMDA] discovered andromdapp type --> 'richclient'

Please choose the type of application to generate [j2ee, richclient]
j2ee

Please enter the parent directory of your new application directory (i.e. C:/Workspaces): 
/home/will/ideas/easymda3.5

Please enter your first and last name (i.e. Chad Brandon): 
Will Chang

Which kind of modeling tool will you use?
(uml1.4 or uml2 for .xml.zip/.xml/.xmi/.zargo files,
emf-uml22 for .uml files, rsm7 for .emx files) [uml1.4, uml2, emf-uml22, rsm7]: 
emf-uml22

Please enter the name (maven project description) of your J2EE project (i.e. Animal Quiz): 
easymda

Please enter an id (maven artifactId) for your J2EE project (i.e. animalquiz): 
easymda

Please enter a version for your project (i.e. 1.0-SNAPSHOT): 


Please enter a version for your project (i.e. 1.0-SNAPSHOT): 
1.0-SNAPSHOT

Please enter the root package name (maven groupId) for your J2EE project (i.e. org.andromda.samples.animalquiz): 
com.standino

Would you like an EAR or standalone WAR? [ear, war]: 
ear

Please enter the type of transactional/persistence cartridge to use (enter 'none' if you don't want to use one) [hibernate, ejb, ejb3, spring, none]: 
spring

Please enter the programming language to be used in service and dao implementations [java, groovy]: 
java

Please enter the database backend for the persistence layer [h2, hypersonic, mysql, oracle, db2, informix, mssql, pointbase, postgres, sybase, sabdb, progress, derby, javadb]: 
db2

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]: 
yes

Will your project have a web user interface? [yes, no]: 
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]: 
jsf

Would you like a standalone or portlet JSF application (Note: Liferay is the only currently supported portlet container)? [standalone, portlet]: 
standalone

Would you like to be able to expose your services as web services? [yes, no]: 
yes

Would you like to use Axis, XFire, CXF, or Sun's Jax-WS as your SOAP Stack? [axis, xfire, cxf, jaxws]: 
jaxws

Would you like to use the embedded Jetty web server (Maven plugin)? [yes, no]: 
yes

KissMDA

https://github.com/crowdcode-de/kissmda

mvn archetype:generate -DarchetypeGroupId=de.crowdcode.kissmda.maven -DarchetypeArtifactId=kissmda-maven-app-archetype -DarchetypeVersion=1.0.0 -DgroupId="com.mytest" -DartifactId="mytestapp" -DprojectName="mytestapp" -DprojectDescription="This is my first project with KissMDA"

RTC plugin Restful web service

Create project

mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.4:generate

/home/will/ideas/RTCPlugin

will@will RTCPlugin$ mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.4:generate
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- andromdapp-maven-plugin:3.4:generate (default-cli) @ standalone-pom ---
INFO  [AndroMDA] discovered andromdapp type --> 'j2ee'
INFO  [AndroMDA] discovered andromdapp type --> 'richclient'

Please choose the type of application to generate [j2ee, richclient]
j2ee

Please enter the parent directory of your new application directory (i.e. C:/Workspaces): 
/home/will/ideas/RTCPlugin

Please enter your first and last name (i.e. Chad Brandon): 
Will Chang

Which kind of modeling tool will you use?
(uml1.4 or uml2 for .xml.zip/.xml/.xmi/.zargo files,
emf-uml22 for .uml files, rsm7 for .emx files) [uml1.4, uml2, emf-uml22, rsm7]: 
uml1.4

Please enter the name (maven project description) of your J2EE project (i.e. Animal Quiz): 
RTC plugin Restful web service 

Please enter an id (maven artifactId) for your J2EE project (i.e. animalquiz): 
rtcpluginrestfulws

Please enter a version for your project (i.e. 1.0-SNAPSHOT): 


Please enter a version for your project (i.e. 1.0-SNAPSHOT): 
1.0-SNAPSHOT

Please enter the root package name (maven groupId) for your J2EE project (i.e. org.andromda.samples.animalquiz): 
com.ibm.dsw.rtc.plugin.rest

Would you like an EAR or standalone WAR? [ear, war]: 
ear

Please enter the type of transactional/persistence cartridge to use (enter 'none' if you don't want to use one) [hibernate, ejb, ejb3, spring, none]: 
spring

Please enter the programming language to be used in service and dao implementations [java, groovy]: 
java

Please enter the database backend for the persistence layer [h2, hypersonic, mysql, oracle, db2, informix, mssql, pointbase, postgres, sybase, sabdb, progress, derby, javadb]: 
h2

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]: 
no

Will your project have a web user interface? [yes, no]: 
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]: 
struts

Would you like to be able to expose your services as web services? [yes, no]: 
yes

Would you like to use Axis, XFire, CXF, or Sun's Jax-WS as your SOAP Stack? [axis, xfire, cxf, jaxws]: 
cxf

What is your JAX-WS REST provider/consumer media type?
(none for JAX-WS only, xml for JAX-RS only, or appxml, json, atom, plain, multipart, fastinfoset, yaml) [none, xml, appxml, json, atom, plain, fastinfoset, yaml, multipart]: 
json

Would you like to use the embedded Jetty web server (Maven plugin)? [yes, no]: 
no
-----

修改app/pom.xml 设置jboos7新的部署目录 ${jboss.home}/standalone/deployments/

需要找到一种方式来编辑uml,最好是可以使用eclipse papyrus. 现在需要使用3.5来试一试。

Comments

comments powered by Disqus