Wednesday, November 19, 2014

Creating a new AndroMDA 3.5-SNAPSHOT project

This will detail the basic steps to create a new Andromda 3.5-SNAPSHOT project This assumes you have maven 3.x installed and java 1.7 1 - Create a new maven project from the maven archetypes:
 mvn archetype:generate -DgroupId=com.mdahatter.androtest -DartifactId=sampleapplication -Dversion=1.0-SNAPSHOT  
2 - Accept all of the defaults to create a new project 3 - Navigate into the newly created project folder and edit the pom.xml 4 - Add the following section after the dependencies section:
 <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>  
5 - edit the /conf/settings.xml file in your maven install directory %M2_HOME% add the following section:
 <profile>  
   <id>default</id>  
   <activation>  
     <activeByDefault>true</activeByDefault>  
   </activation>  
   <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>  
 </profile>  
6 - From this folder run mvn without any arguements. This will download the AndroMDA 3.5-SNAPSHOT plugin for use. 7 - You can delete the folder you just created, you do not need that anymore. The AndroMDA 3.5-SNAPSHOT plugin is now in your mvn repository. 8 - Run the following command to create a new Andromda project:
 mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.5-SNAPSHOT:generate  

Friday, September 28, 2012

Unit Testing AndroMDA generated EJB3 from Eclipe using JUNIT and Glassfish3.1

 **TODO** detail the customizations to the Andromda files to support the connection to the Glassfish container from a JUnit test.

Add the following to the ServiceDelegate.vsl file for Andromda.

Properties prop = new Properties();
        prop.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.impl.SerialInitContextFactory");
        prop.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
        prop.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
        this.setProperties(prop);

Thursday, September 27, 2012

AndroMDA 3.4 and Glassfish EJB3 persistence layer

After long wait AndroMDA 3.4 has finally been officially released. The build seems extremely stable and an excellent product. Congratulations and many thanks to the AndroMDA team. Information on using AndroMDA can be found at: www.andromda.org *Warning* the last time I checked all of the documentation found on that main site was outdated. The tutorials would not work exactly as described. I have not checked to see if this has been updated since. I always get my information from the forums, which are active and the Andromda team is great about answering questions posted there, and keeping the community up to date with whatever is happening with AndroMDA. I have been using AndroMDA for code generation of the middle tier/backend code for projects for the past 4 years. The environment I target is Glassfish with MySQL or PostGres database. EJB3/Hibernate persistence, and generally will enable webservices (jsr-181) as well. AndroMDA projects will *not* deploy properly to Glassfish from initial generation and will require some massaging. (The default platform for AndroMDA ejb3 projects is JBoss.)

Step 1 - Generate blank project. 
From a command prompt issue the statement: mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.4:generate Run through the various questions. Select EJB3/JPA for the persistence layer and Hibernate. Select uml2 for the uml format. This will create a blank project directory with the maven scripts and a blank UML diagram template under the MDA folder. If you attempt to compile this at this point, it will fail. There are missing versions for a couple of the dependencies in the core/pom.xml folder.

Step 2 - fix core/pom.xml dependency issue open the pom.xml file located under the core folder. 
Search for the dependency sections for the slf4j-api and slf4j-log2j12. Comment these two sections out.

Step 3 - Compile project. 
From the root of the newly created project folder run the command: mvn This will compile the project and in the process bring down some additional artifacts, namely the andromda profiles needed for the UML modelling portion.

 Step 4- Open blank UML project using MagicDraw or other compatible UML tool. 
Open the blank uml project created by Andromda. This will be located under the mda/src/main/uml folder.

Step 5 - Point MagicDraw to the Andromda profiles
This will fail the first time you open the model if you have not defined the location of your maven2 repository. In magicdraw, under the Options-Environment-Path Variables menu be sure to modify (or add) the variable: maven2.repository and point it to your .m2/repository directory (wherever you created it with maven2. Mine is under c:/users/myname/.m2/repository

 Step 6 - Create a basic UML class diagram, and annotate classes. 
Create a new class diagram, and add a new class.. annotate the class with the Entity stereotype (make sure you select the andromda entity, not the uml2 one...)

Step 7 - Export UML2 diagram 
File-Save the updated model, and then File-Export-UML2 the model.

Step 8 - Compile project
From a command prompt type mvn This will generate code, but will likely fail with additional issues due to the generation of files needed for JBoss, but unnecessary for a Glassfish deployment.

Step 9 - Fix EJBContainer dependency issues 

Step 10 - Import into Eclipse 

Step 11 - Create blank MySQL schema 

Step 12 - Add jdbc datasource to Glassfish 

Step 13 - Modify default pom.xml

The naming convention for the jdbc datasources used by JBoss is different than glassfish. In the main pom.xml located in the root of your project, modify the following section as shown:
 <dataSource.name>${application.id}</dataSource.name>
<dataSource>jdbc/${dataSource.name}</dataSource>
*** also need to remove the 'provided' scope for commons-collections. Find the following section:
<dependency>
  <groupId>commons-collections</groupId>
  <artifactId>commons-collections</artifactId>
  <version>3.2.1</version>
  <!-- JBoss contains a version which causes a classloader conflict unless not bundled -->
  <scope>provided</scope>
</dependency>
Remove the 'provided' scope. (you can delete that line)

Step 14 - Add mergeLocation property to the EJB3 section of andromda.xml file
**Also need to change the persistenceProvider to glassfish in here...

Step 15 - Add customized files to custom/ejb3 folder
Step 15a) - ejb-jar.vsl
Step 15b) - cartridge.xml remove ejbcontainer and other classes.

The SessionLocal, SessionRemote, SessionInterface,ServiceDelegate,ServiceDelegateBase and ServiceLocator is genereted in the wrong jar by default... it needs to be generated in the commons package, not the core.  The cartridge.xml file cannot be replaced in AndroMDA the same way the .vsl template files can, but AndroMDA does provide a 'mergeMapping' mechanism which can be used to modify the andromda.xml file.  To make the necessary changes, create a new file called EJB3MergeMappings.xml and place it in the folder: %YourProjectFolder%\mda\src\main\config\mappings folder.  This file should contain the below code (approximately...cut the sections from the cartridge.xml from the andromda ejb3 cartridge jar located in your maven repository to ensure you have the exact sections..also... the below does not contain all of the sections...).  In your andromda.xml file, uncomment the line:
file:${conf.dir}/mappings/EJB3MergeMappings.xml 

Note: You will also have to modify your common/pom.xml to add the ejb jar dependency or the interfaces will not compile properly...
 <mappings name="EJB3MergeMappings">    
   <mapping>  
     <from><![CDATA[<template  
     path="templates/ejb3/ServiceDelegate.vsl"  
     outputPattern="$generatedFile"  
     outlet="services"  
     overwrite="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]></from>  
     <to>  
       <![CDATA[<template  
     path="templates/ejb3/ServiceDelegate.vsl"  
     outputPattern="$generatedFile"  
     outlet="commons"  
     overwrite="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]>  
     </to>  
   </mapping>  
 <mapping>  
     <from><![CDATA[<template  
     path="templates/ejb3/ServiceDelegateBase.vsl"  
     outputPattern="$generatedFile"  
     outlet="services"  
     overwrite="true"  
     outputToSingleFile="true"  
     outputOnEmptyElements="false">  
     <modelElements>  
       <modelElement variable="services">  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]></from>  
     <to>  
       <![CDATA[<template  
     path="templates/ejb3/ServiceDelegateBase.vsl"  
     outputPattern="$generatedFile"  
     outlet="commons"  
     overwrite="true"  
     outputToSingleFile="true"  
     outputOnEmptyElements="false">  
     <modelElements>  
       <modelElement variable="services">  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]>  
     </to>  
   </mapping>    
 <mapping>  
     <from><![CDATA[<template  
     path="templates/ejb3/ServiceLocator.vsl"  
     outputPattern="$generatedFile"  
     outlet="services"  
     overwrite="true"  
     outputToSingleFile="true"  
     outputOnEmptyElements="false">  
     <modelElements>  
       <modelElement variable="services">  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]></from>  
     <to>  
       <![CDATA[<template  
     path="templates/ejb3/ServiceLocator.vsl"  
     outputPattern="$generatedFile"  
     outlet="commons"  
     overwrite="true"  
     outputToSingleFile="true"  
     outputOnEmptyElements="false">  
     <modelElements>  
       <modelElement variable="services">  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]>  
     </to>  
   </mapping>  
      <mapping>  
     <from><![CDATA[<template   
     path="templates/ejb3/SessionInterface.vsl"  
     outputPattern="$generatedFile"   
     outlet="session-beans"   
     overwrite="true"  
     generateEmptyFiles="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]></from>  
     <to>  
       <![CDATA[<template   
     path="templates/ejb3/SessionInterface.vsl"  
     outputPattern="$generatedFile"   
     outlet="commons"   
     overwrite="true"  
     generateEmptyFiles="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade"/>  
       </modelElement>  
     </modelElements>  
   </template>]]>  
     </to>  
   </mapping>   
      <mapping>  
     <from><![CDATA[<template   
     path="templates/ejb3/SessionLocal.vsl"  
     outputPattern="$generatedFile"   
     outlet="session-beans"  
     overwrite="true"   
     generateEmptyFiles="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade">  
           <property name="viewTypeLocal"/>  
         </type>  
       </modelElement>  
     </modelElements>  
   </template>]]></from>  
     <to>  
       <![CDATA[<template   
     path="templates/ejb3/SessionLocal.vsl"  
     outputPattern="$generatedFile"   
     outlet="commons"  
     overwrite="true"   
     generateEmptyFiles="true">  
     <modelElements variable="service">  
       <modelElement>  
         <type name="org.andromda.cartridges.ejb3.metafacades.EJB3SessionFacade">  
           <property name="viewTypeLocal"/>  
         </type>  
       </modelElement>  
     </modelElements>  
   </template>]]>  
     </to>  
   </mapping>        
 </mappings>  

Sunday, June 24, 2012

Using Andromda 3.4-SNAPSHOT to deploy to Glassfish

Glassfish requires a few modifications to the andromda files before it will deploy properly. The ejb-jar.xml must be modified to change instances of and to and The format of the jdbc jndi parameter in the main pom.xml must be modified. Here is how: Modifying the ejb-jar.xml: Generate a new andromda project. In the mda/src/main/config folder create the following directory structure: custom/ejb3/templates/ejb3/config folder. Create a new ejb-jar.xml.vsl file in this folder. Add the following to that folder:
 <?xml version="1.0" encoding="${xmlEncoding}"?>  
 <ejb-jar  
   xmlns="http://java.sun.com/xml/ns/javaee"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
             http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"  
   version="3.0">  
   <description><![CDATA[No Description.]]></description>  
   <display-name>Generated by AndroMDA EJB3 Cartridge</display-name>  
   <enterprise-beans>  
 #foreach ($service in $services)  
     <session>  
       <description>  
         <![CDATA[  
         $service.getDocumentation("", 64, false)  
         ]]>  
       </description>  
       <ejb-name>${service.serviceName}</ejb-name>  
 ##  
 ## Only define the remote business interface if the bean is NOT a Seam component  
 ##  
 #**##if ($service.viewTypeLocal)  
       <business-local>${service.fullyQualifiedServiceLocalInterfaceName}</business-local>  
 #**##end  
 #**##if ($service.viewTypeRemote && !$service.seamComponent)  
       <business-remote>${service.fullyQualifiedServiceRemoteInterfaceName}</business-remote>  
 #**##end  
       <ejb-class>${service.fullyQualifiedServiceName}</ejb-class>  
       <session-type>${service.type}</session-type>  
 #**##if ($service.transactionManagementBean)  
       <transaction-type>Bean</transaction-type>  
 #**##else  
       <transaction-type>Container</transaction-type>  
 #**##end  
 #**##foreach($envEntry in $service.getEnvironmentEntries(true))  
       <env-entry>  
         <env-entry-name>${envEntry.name}</env-entry-name>  
 #if ($envEntry.type.primitive)  
 #set ($typeName = ${envEntry.type.wrapperName})  
 #else  
 #set ($typeName = ${envEntry.type.fullyQualifiedName})  
 #end  
         <env-entry-type>$converter.getJavaLangTypeName($typeName)</env-entry-type>  
         <env-entry-value>${envEntry.defaultValue.replace('"','')}</env-entry-value>  
       </env-entry>  
 #**##end  
     </session>  
 #end  
 #foreach ($manageable in $manageables)  
     <session>  
       <description>  
         <![CDATA[  
         $manageable.getDocumentation("", 64, false)  
         ]]>  
       </description>  
       <ejb-name>${manageable.manageableServiceName}</ejb-name>  
       <business-remote>${manageable.fullyQualifiedManageableServiceName}</business-remote>  
       <ejb-class>${manageable.fullyQualifiedManageableServiceBaseName}</ejb-class>  
       <session-type>Stateless</session-type>  
       <transaction-type>Container</transaction-type>  
     </session>  
 #end  
 #foreach ($entity in $entities)  
     <session>  
       <description>  
         <![CDATA[  
         $entity.getDocumentation("", 64, false)  
         ]]>  
       </description>  
       <ejb-name>${entity.daoName}</ejb-name>  
       <business-local>${entity.fullyQualifiedDaoName}</business-local>  
       <ejb-class>${entity.fullyQualifiedDaoImplementationName}</ejb-class>  
       <session-type>Stateless</session-type>  
       <transaction-type>Container</transaction-type>  
     </session>  
 #end  
   </enterprise-beans>  
 #if (${seamEnabled} == 'true')  
   <interceptors>  
     <interceptor>  
       <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>  
     </interceptor>  
   </interceptors>  
 #end  
   <assembly-descriptor>  
 #foreach ($interceptor in $interceptors)  
 ##  
 ## Default interceptors  
 ##  
 #**##if ($interceptor.defaultInterceptor)  
 #* *##if (!$defaultInterceptorExists)  
     <interceptor-binding>  
       <ejb-name>*</ejb-name>  
 #*  *##set ($defaultInterceptorExists = true)  
 #* *##end  
       <interceptor-class>${interceptor.fullyQualifiedName}</interceptor-class>  
 #**##end  
 #end  
 #if ($defaultInterceptorExists)  
     </interceptor-binding>  
 #end  
 #foreach ($service in $services)  
 ##  
 ## Service listener - lifecycle callbacks are defined as an interceptor  
 ##  
 #**##set ($interceptors = $service.interceptorReferences)  
 #**##if ($collectionUtils.size($interceptors) >= 1 || $service.listenerEnabled)  
     <interceptor-binding>  
       <ejb-name>${service.serviceName}</ejb-name>  
 #* *##if ($service.listenerEnabled)  
       <interceptor-class>${service.fullyQualifiedServiceListenerName}</interceptor-class>  
 #* *##end  
 #* *##foreach ($interceptor in $interceptors)  
       <interceptor-class>${interceptor.fullyQualifiedName}</interceptor-class>  
 #* *##end  
 #* *##if ($service.excludeDefaultInterceptors)  
       <exclude-default-interceptors/>  
 #* *##end  
     </interceptor-binding>  
 #**##end  
 #end  
 ##  
 ## Define method level interceptors for session beans  
 ##  
 #foreach ($service in $services)  
 #**##foreach ($operation in $service.businessOperations)  
 #* *##set ($interceptors = $operation.interceptorReferences)  
 #* *##if ($collectionUtils.size($interceptors) >= 1)  
     <interceptor-binding>  
       <ejb-name>${service.serviceName}</ejb-name>  
 #*  *##foreach ($interceptor in $interceptors)  
       <interceptor-class>${interceptor.fullyQualifiedName}</interceptor-class>  
 #*  *##end  
       <method>  
         <method-name>${operation.name}</method-name>  
 #*  *##if (!$operation.arguments.empty)  
         <method-params>  
 #*   *##foreach ($argument in $operation.arguments)  
           <method-param>${argument.type.fullyQualifiedName}</method-param>  
 #*   *##end  
         </method-params>  
 #*  *##end  
       </method>  
 #*  *##if ($operation.excludeClassInterceptors)  
       <exclude-class-interceptors/>  
 #*  *##end  
 #*  *##if ($operation.excludeDefaultInterceptors)  
       <exclude-default-interceptors/>  
 #*  *##end  
     </interceptor-binding>  
 #* *##end  
 #**##end  
 #end  
 #foreach ($mdb in $mdbs)  
 ##  
 ## Message-driven bean listener - lifecycle callbacks are defined as an interceptor  
 ##  
 #**##set ($interceptors = $mdb.interceptorReferences)  
 #**##if ($collectionUtils.size($interceptors) >= 1 || $mdb.listenerEnabled)  
     <interceptor-binding>  
       <ejb-name>${mdb.messageDrivenName}</ejb-name>  
 #* *##if ($mdb.listenerEnabled)  
       <interceptor-class>${mdb.fullyQualifiedMessageDrivenListenerName}</interceptor-class>  
 #* *##end  
 #* *##foreach ($interceptor in $interceptors)  
       <interceptor-class>${interceptor.fullyQualifiedName}</interceptor-class>  
 #* *##end  
 #* *##if ($mdb.excludeDefaultInterceptors)  
       <exclude-default-interceptors/>  
 #* *##end  
     </interceptor-binding>  
 #**##end  
 #end  
 #if (${seamEnabled} == 'true')  
     <interceptor-binding>  
       <ejb-name>*</ejb-name>  
       <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>  
     </interceptor-binding>  
 #end  
   </assembly-descriptor>  
 </ejb-jar> 
Modify the file: /mda/src/main/config/andromda.xml in the ejb3 section add the following:
 <property name="mergeLocation">${conf.dir}/custom/ejb3</property>  
That will format the ejb deployment descriptor properly. 2 - modify the main pom.xml Find and modify the following two parameters as shown below:
   <dataSource.name>${application.id}</dataSource.name>  
     <dataSource>jdbc/${dataSource.name}</dataSource>  
Now you should be able to successfully deploy your project to glassfish. Do not forget to set up the proper jndi jdbc resources within the glassfish admin console. That is outside the scope of this blog.

Tuesday, December 14, 2010

Andromda 3.4 -> Glassfish v3 -> JPA->Hibernate->MYSQL

Several issues arise right now with the andromda 3.4-SNAPSHOT build. Could not compile due to incomplete code generated by the JSF-Cartridge. Modified the files:
%JSF_CARTRIDGE%/templates/jsf/utils/ControllerBase.java, and JsfVariableResolver.java
to resolve.

Also, the application.xml that is generated is invalid ... open application.xml and move the <description> tag above the <display-name> tag.

Configuration of Glassfish:
Installed fresh install of Glassfish.
Created a jdbc connection pool in the glassfish v3 admin console.
Common Tasks>Create New JDBC Connection Pool

in the additional parameters section:
servername: localhost
port: 3306
user: user
password: pass
databasename: newdbname

Deploy the mysql connector (mysql-connector-java-5.1.5-bin.jar' into the folder:
%glassfish_install_folder%\domains\domain1\lib\ext


Modifying Andromda build.
For this test I have previously reverse engineered a model from an existing schema which I already have installed in my mysql db. I generated a new clean andromda 3.4-SNAPSHOT project, and tinkered to get it to successfully build. Upon deployment to Glassfish, it complained about missing hibernate classes.

Modify main pom.xml to include hibernate .jars:

<dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>3.6.0.Final</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>3.6.0.Final</version>
                <scope>compile</scope>
            </dependency>

Wednesday, December 1, 2010

Creating Liferay 6 portlets using Andromda

I am going to attempt to build a liferay 6 portlet using Andromda 3.4-SNAPSHOT.
This initial attempt is just to get a portlet running and deployed, and this blog is really intended as documentation of the steps for my reference... so reader beware.

Step 1 - Generate initial andromda project.
I have previously installed  maven 2.2.1 and Java JDK v 1.6.0_22

I created a folder c:/development/andromda_liferay6

From a command line I run the command:

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


This will generate a new andromda project:

I created a j2ee project, uml2, no persistence cartridge, jsf, portlet, icefaces support.

Edited the mda\src\main\uml\sample_project.xml using MagicDraw 16.5 community version
Added a state diagram with one state and one controller class.
Tested compiling from the command line with the mvn command from the root folder of the sample_project folder.  The project compiled with a number of isses, look like missing icefaces components.  Ran the command mvn eclipse:eclipse to generate the eclipse project so that I could review the code inside of Eclipse.  Got the following error:

"Cant canonicalize system path:"  --->  had to change line in the web/pom.xml from

<targetPath>${project.basedir}/target/src/main/webapp</targetPath>
to:

<targetPath>../target/src/main/webapp</targetPath> 

Compiled ok. Open in Eclipse (Helios).

Wednesday, October 6, 2010

Creating Glassfish webservices using Andromda.

As part of our ongoing development I needed to add webservice support to our application.  During my initial Andromda setup I had indicated that we would not be using webservices so the build was not set up to support this... so I knew this would likely require a configuration change.

Since most of the configurations are done via the andromda.xml file located under the MDA/src/main/config folder of the project, this was the first place I looked.

Sure enough, I found a setting called: webServiceEnabled which was set to false.  I switched this to true.

Then I opened my uml model and proceeded annotate one of my Service methods with the stereotype of 'WebServiceOperation' ...exported model and saved it, recompiled...

And was getting an annoying class not found error.  After investigating the ServiceWSInterface.java file I found an annotation which looked like this:
@org.jboss.ws.annotation.PortComponent(contextRoot = ...

Since everything else in the file looked good, and since I was not using JBoss for my persistence, I should be able to just remove the offending line from the andromda template as a worse case scenario.

I cracked open the andromda cartridge template WebServiceInterface.vsl and found the line that was inserting the offending piece of code.  I noticed around that block of code was an if statement saying to add that line only if the persistenceContainerName = jboss.

After further inspection of the andromda.xml config file, I found the following property:


property name="persistenceContainerName" which was set to jboss... changed that to glassfish, recompiled and everything seems to be working properly now.

Hope this helps someone else out there.

Saturday, August 14, 2010

Reverse engineering a MySQL schema into JPA classes using AndroMDA

We are looking to use a third party product in our system, and want to integrate our domain with theirs.  I have set up the db schema for the third party in MySQL.  What I am trying to do is create a separate EJB service class to access this third party database.  To do that I want to reverse the database into EJB3 entity classes using AndroMDA.

AndroMDA has an ANT pluging called Schema2XMI which is supposed to automatically generate the domain objects from a schema.  In this post I will attempt to do that.

So far, I have generated a new Andromda project (see previous posts on how to do this).

I have downloaded the AndroMDA binary and exploded it into the folder C:\programs\andromda_bin_exploded
In the root of the new andromda project (same folder as the root pom.xml) I have created the file build.xml and put the following contents inside of it:

           <property name="andromda.lib.dir" value="C:\programs\andromda_bin_exploded\andromda\org\andromda"/>             <property name="andromda.dependency.dir" value="C:\programs\andromda_bin_exploded\lib"/>             <path id="andromda.classpath">         <fileset dir="${andromda.lib.dir}">           <include name="andromda-core/*/andromda-core-*.jar"/>           <include name="andromda-utils/*/andromda-utils-*.jar"/>           <include name="andromda-schema2xmi/*/andromda-schema2xmi-*.jar"/>           <include name="ant/andromda-ant-task/*/andromda-ant-task-*.jar"/>           <include name="metafacades/andromda-metafacades-emf-uml2/*/andromda-metafacades-emf-uml2-*.jar"/>           <include name="metafacades/andromda-metafacades-uml/*/andromda-metafacades-uml-*.jar"/>           <include name="metafacades/andromda-metafacades-uml14/*/andromda-metafacades-uml14-*.jar"/>           <include name="repositories/andromda-repository-emf/*/andromda-repository-emf-*.jar"/>           <include name="repositories/andromda-repository-mdr/*/andromda-repository-mdr*.jar"/>           <include name="repositories/andromda-repository-mdr-uml14/*/andromda-repository-mdr-uml14*.jar"/>           <include name="repositories/andromda-repository-emf-uml2/*/andromda-repository-emf-uml2-*.jar"/>           <include name="translationlibraries/andromda-ocl-query-library/*/andromda-ocl-query-library-*.jar"/>           <include name="translationlibraries/andromda-ocl-translation-core/*/andromda-ocl-translation-core-*.jar"/>           <include name="translationlibraries/andromda-ocl-translation-testsuite/*/andromda-ocl-translation-testsuite-*.jar"/>           <include name="translationlibraries/andromda-ocl-validation-library/*/andromda-ocl-validation-library-*.jar"/>           <include name="templateengines/andromda-templateengine-velocity/*/andromda-templateengine-velocity-*.jar"/>           <include name="cartridges/andromda-java-cartridge/*/andromda-java-cartridge-*.jar"/>         </fileset>         <fileset dir="${andromda.dependency.dir}">           <include name="commons-beanutils/commons-beanutils/*/commons-beanutils-*.jar"/>           <include name="commons-collections/commons-collections/*/commons-collections-*.jar"/>           <include name="commons-digester/commons-digester/*/commons-digester-*.jar"/>           <include name="commons-dbutils/commons-dbutils/*/commons-dbutils-*.jar"/>           <include name="commons-cli/commons-cli/*/commons-cli-*.jar"/>           <include name="commons-lang/commons-lang/*/commons-lang-*.jar"/>           <include name="commons-logging/commons-logging/*/commons-logging-*.jar"/>           <include name="log4j/log4j/*/log4j-*.jar"/>           <include name="velocity/velocity/*/velocity-*.jar"/>           <include name="xerces/xercesImpl/*/xercesImpl-*.jar"/>           <include name="xml-apis/xml-apis/*/xml-apis-*.jar"/>           <include name="jmi/jmi/*/jmi-*.jar"/>           <include name="jmi/jmiuml/*/jmiuml-*.jar"/>           <include name="jmi/mof/*/mof-*.jar"/>           <include name="org/netbeans/mdr/jmiutils/*/jmiutils-*.jar"/>           <include name="org/netbeans/mdr/mdrapi/*/mdrapi-*.jar"/>           <include name="org/netbeans/mdr/nbmdr/*/nbmdr-*.jar"/>           <include name="org/netbeans/mdr/openide-util/*/openide-util-*.jar"/>           <include name="org/eclipse/**/*.jar"/>           <include name="*.jar"/>         </fileset>       </path>       <target name="schema2xmi">         <java classname="org.andromda.schema2xmi.Schema2XMI" fork="true">           <classpath>             <path refid="andromda.classpath"/>           </classpath>           <arg value="-i"/>           <arg value="file:${basedir}/mda/src/uml/schema2xmi/input.xml"/>           <arg value="-u"/>           <arg value="${dbuser}"/>           <arg value="-p"/>           <arg value="${dbpass}"/>           <arg value="-c"/>           <arg value="jdbc:mysql://l127.0.0.1:3306/app"/>           <arg value="-d"/>           <arg value="com.mysql.jdbc.Driver"/>           <arg value="-m"/>           <arg value="file:${basedir}/mda/src/mappings/MySQLMappings.xml"/>           <arg value="-o"/>           <arg value="${basedir}/mda/src/uml/output.xmi"/>           <arg value="-P"/>           <arg value="com::example::app"/>           <arg value="-I"/>           <arg value="Identifier"/>           <arg value="-C"/>           <arg value="Entity"/>           <arg value="-V"/>           <arg value="@andromda.persistence.table"/>           <arg value="-v"/>           <arg value="@andromda.persistence.column"/>         </java>       </target> 

Friday, August 6, 2010

Unit testing EJB3 using JBoss Microcontainer, Andromda generated tests and TestNG

Using Andromda to generate your EJB code, including unit test classes is pretty cool, albeit difficult to get working the first time...   I am currently using Andromda 3.3 since it is the latest released version of Andromda.  It works well once set up initially.

In this post I just want to give a basic overview of how the unit testing works.  It can look very convoluted and can be really difficult to troubleshoot the first time since it may be unclear exactly how it works...

The unit tests are created in the package /core/src/test/java
In this package you will see two files created:  EJB3Container.java and yourClassNameTest.java
The EJB3Container is a common EJB3 container which is set up to use JBoss 3.2.0.ga by default. 
The other class is the test class specific to your service class.  Andromda will generate one of these for each class annotated with the <> stereotype.

Additionally you will see a package /core/src/test/resources which will contain a host of configuration files with various settings that can be changed to affect your unit testing container.  The first two files you will probably be concerned with are the testng.xml file and the embedded-jboss-beans.xml file.

The testng.xml file contains a list of all of the classes that testng will instantiate and inject into the unit testing container.  It is important that testng be configured to use this file, otherwise the andromda test will not work.

The embedded-jboss-beans.xml file contains settings for the connection of the JBoss microcontainer to your local database (amongst other things)... make sure you have this modified appropriately to access your local environment.

The basic flow of the TestNG tests with the andromda build is as follows:

For testing within Eclipse:
TestNG Eclipse Plugin is loaded, it is pointed to the testng.xml file via the configuration screen in Eclipse.  TestNG plugin loads up the EJB3Container and your Test classes.

Your test class is run.  Since the EJB3Container has been previously loaded, your test classes can access the EJB local and/or remote interfaces via JDNI calls to the InitialContext.

Method calls to the EJBs are made in the test class... these get run inside of the EJB3Microcontainer, and the results are returned to the test classes and assertations can be made on them at that point.

Tuesday, August 3, 2010

Unit testing of EJBs using AndroMDA, TestNG and JBoss Microcontainer

I am in the process of trying to get AndroMDA 3.3 running agains the new JBoss Microcontainer and using the latest TestNG version.

Before doing that, I decided to create a new AndroMDA model with a really simple service (one method) one entity with one String attribute and an accompanying ValueObject (again, one String method).



Generated the source using AndroMDA.  This is an EJB3 project, btw.

Right off the bat some things were broken... the generated test class was broken due to changes in the AndroMDA generated 'ServiceLocator'... several method signatures, etc.

Also, testng.jar does not import by default after doing the mvn eclipse:eclipse... I changed the main pom.xml for testng to tell it to include the .jar on compile and I upped testng to the latest verson:


       


I am also using a fresh Eclipse install, so had to install the testNG eclipse plugin to get the tests to run from inside of Eclipse... you can find the plugin install information at:  http://testng.org/doc/eclipse.html


Upon first trying to run the TestNG in debug mode, it did not work.... a little reading on the TestNG site revealed that you need to set up a debug configuration within Eclipse.  To do this, select run--Debug Configurations...

Select TestNG from the list and create a new configuration... in that configuration , under the 'Suite' section, click the browse button and select testng.xml file.  This will inject any classes defined in this xml file whenever TestNG is run... you need the EJB3Container to be injected on each test run.


At this point you can click 'Debug' to attempt to debug your test class.  This will likely fail for you with a runtime exception stating "java.lang.NoSuchMethodError: org.jboss.ejb3.KernelAbstractionFactory.setKernel(Lorg/jboss/kernel/Kernel;)"... a quick search of the Andromda forums revealed that there appears to be conflicting JBoss .jars.

http://forum.andromda.org/viewtopic.php?t=4410&highlight=testng+eclipse

Removal of the duplicate .jars should do the trick...

M2_REPO/org/jboss/jboss-ejb3-client/4.0.5-GA/jboss-ejb3-client-4.0.5-GA.jar
M2_REPO/org/jboss/jboss-aop-jdk50-client/4.0.5-GA/jboss-aop-jdk50-client-4.0.5-GA.jar


(I removed them from the /core/pom.xml so that I would not have to keep going back in and removing these...)

Note, right now I am just trying to get the JBoss Microcontainer alpha 9 version to run... later I am going to attemp to get the latest version going...

Note:  One other things... make sure you add /core/src/test/resources as a Source folder under Java Build Path -- Source Tab for your project.  Otherwise you will get the runtime exception: Cannot find embedded-jboss-beans.xml

Note 2:  OK... so the next problem I ran into was  the exception:
java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager

I broke open the hibernate annotations .jar and noted that the above class is not in it... after a bit of searching on the Andromda forum, I found someone mention changing the main pom.xml hibernate sections as follows:



           
The change is to set both version to 3.2.0.ga versions... the versions in the one created for me were different and incompatible... you may be able to bring these up to the latest hibernate versions too... I have not tried that yet, but will be in the next couple of days.

run:
mvn install -Dmaven.test.skip
to bring down these new jars... note the -Dmaven.test.skip command which will tell it not to try to run the unit tests... without this, the build will fail ....following this run:
mvn eclipse:eclipse
Refresh your Eclipse environment...  (remember you will have to remove the .jars from the previous step again.  This step should be done first really, but I am just documenting the order I am running into these issues.)

One last step... I needed to modify the file core/src/test/resources/embedded-jboss-beans.xml to set the database username and password...

Find the section for the database you are using (mysql in this case)... add/or modify the username and/or password to match your local installation.









Tuesday, June 29, 2010

Speeding up Andromda

Andromda is a bit of a hog when you are trying to do a maven compile.  We have a pretty complex model, and we use Andromda to generate all of our backend classes.  On my machine our 'normal' maven build takes approximately 2 min and 45 secs to do the andromda generate, and compile the classes.  Acceptable after a model change, since I model relatively rarely.  Too much time when you are doing normal coding activities.

Here are a few tips:

You can do a:

Skip unit tests:
mvn -Dmaven.test.skip to skip unit tests.

Do an offline build:
mvn -o this will do an 'offline' build, saving the check of all of the SNAPSHOT dependencies.  Andromda has a lot of them!

Skip Andromda model validation:
mvn -Dvalidation=false  this skips the validation of the model, and will go right into the compile.  This saves about 45 seconds on my machine.


Use andromda server:
There is a mvn mda\pom.xml andromda:start-server
This loads a memory resident verion of andromda and loads the xml into memory.  This will monitor the model as well and auto-reload it into memory apon changes.  In a separate command window you can then issue your normal andromda commands, and it will trigger this 'server window' to perform the andromda portion of your build.  Everything seemed to work with this, but when I did my build I got some compile errors that I did not have doing the non server build.... maybe have a path issue or something... going to have to look into this further.  This method on my machine compiled in 30 seconds, saving 2mins 15 sec per build... so this will warrent some further investigation.  If anyone has any insight into the andromda server let me know.

Build only the modules you are working on:

You are supposed to be able to run
mvn -f core/pom.xml to compile just the core package, but this totally blows up for me due to dependencies in the common package etc.  Did not have time to frig with this ... again, any insight on getting this going, please let me know.

Friday, June 11, 2010

EJB3 - JBOSS - Andromda created -- deployment

OK.

So the ear built fine, now to get it to deploy properly...

I have installed JBOSS v5.0.1 on my machine.  Tried deploying the ear by copying it into:
%JBOSSDeployFolder%\server\default\deploy

Starting getting erros like:

error due to the following reason(s): org.jboss.xb.binding.JBossXBRuntimeException: Element {http://java.sun.com/xml/ns/javaee}jboss is not bound as a global element.




I realized that the jboss.xml file (located inside of the 'yourapp-core.jar' file) which is inside of the .ear had the wrong xml namespace defined.  To fix it you will need to modify the jboss.xml.vsl file, which is located in the cartridge.  As I mentioned in my previous blog post, I maintain a copy of the SNAPSHOT version to keep my changes from being overwritten...   to fix the xml namespace issue, I open my andromda-ejb3-cartridge-1.0-JBOSS.jar file (located in my maven local repository as described in previous blog post).  Modify the /templates/ejb3/config/jboss/jboss.xml.vsl file.  Change the tag to be:

 


I also had problems where JBOSS gave what is IMHO a really bad error message, it said:

* EJB CholesterolGoalDao has defined EJB2.x local component interface of com.wellnessrecord.domain.goals.CholesterolGoalDao but has no localHome; ; Incomplete EJB2.x View [JBMETA-130]

Which after some investigation, means that the ejb-jar.xml created by Andromda is outdated, and uses the old EJB 2.1 conventions...

This file has sections for each of your session beans of the form:

  
           
               
           

            UserServiceBean
            com.wellnessrecord.service.UserServiceRemote
            com.wellnessrecord.service.UserServiceBean
            Stateless
            Container
       


Well, as it turns out, in EJB3 you need the and tags to be of the form and

To fix, modify the file:  /andromda-ejb3-cartridge-1.0-JBOSS.jar\templates\ejb3\config\ejb-jar.xml file.  Replace all occurances of with , with , with and with


Run:
mvn clean
mvn install

Redeploy your .ear to JBOSS.

Friday, September 4, 2009

AndroMDA <> entities

AndroMDA is an excellent open source solution for auto-magically generating code from a UML model. This is a description of my experience trying out the <> stereotype. This stereotype appears to allow you to auto-generate data entry screens just by adding the <> stereotype to an entity.

My steps to generate a manageable entity:

Just a little background, I am developing EJB3 entities using JPA /Hibernate/Mysql.
My EJB/Servlet server is Sun Glassfish v2.1 running the Liferay Portal v5.2.3
Maven v2.0.9, Java JDK v1.6.0_13

'out of the box', Andromda will NOT generate any projects properly for Glassfish. I had to make a modified ejb3 cartridge which works on GLASSFISH. I am not going to describe what I had to do in this post, but will try to remember to detail that at a later time. If anyone needs that info, or just wants a copy of the modified ejb3 cartridge I am using, feel free to ping me.

Step 1 - create a new Andromda project.

From command line>

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

A variety of questions will be asked, below are the options I selected:
Options: 
Rich Client
J2EE
c:/development/andromda_test_portlet
Brad Rideout
UML2
Brad Test Portlet
bradtestportlet
1.0-SNAPSHOT
com.mdahatter.bradportlettest
ear
ejb3
mysql
no
yes
jsf
jsf2
portlet
no
no
Step 2 - modify mda/pom.xml
Since I am using Maven 2.0.9 I had to modify the mda/pom.xml v2.0.8 does not require this step...
find the model.uri section and change it to:

file:${pom.basedir}/src/main/uml/bradportlettest.uml2

Step 3 - Open /mda/src/main/uml/bradportlettest.xml with your uml tool.
I use Magicdraw community version.
The first time you open the project, make sure you set the maven2.repository to your .m2/repository. This can be done in the Options-Environment Options tab.

Step 4 - Create a class diagram
In MagicDraw, right click on the 'Data' folder and click 'New Element--Model', name it 'mdahatter'
Right click on 'mdahatter' and select 'New Element'--'Package' name it com.mdahatter.bradportlettest
Right click on com.mdahatter.bradportlettest and select 'New Diagram'-'class diagram' .. name it 'VOPC'
Add a new class called 'User' with 3 string attributes: 'firstName', lastName', 'email'
Make sure all attributes are public, and use the String [datatype]
Right click on the class and go to the 'Stereotypes' section, select 'Entity' and 'Manageable'... Note: make sure you select the stereotypes from the org.andromda.profile.persistence profile

Step 5 - Export model
Save the model, and select File-Export-EMF UML2 (v1.x) XMI

Step 6 - modify maven pom.xml files

Step 6(A) open the pom.xml in the root of your project.
I modify the org.andromda.cartridge dependency to point to my 1.0-GLASSFISH version of the cartridge. If you are using JBOSS, you should be able to leave this...

org.andromda.cartridges
andromda-ejb3-cartridge
1.0-GLASSFISH
runtime


I also added the Apache maven repository under the area:


apache
Apache Repository
http://people.apache.org/repo/m2-snapshot-repository/


Step 6 (B) Modify the web/pom.xml

In the web/pom.xml find the 'org.apache.myfaces.tomahawk' dependency, and change it like so:


org.apache.myfaces.tomahawk
tomahawk
1.1.7-SNAPSHOT
jar


Step 7 - Run the maven build

From the command line, navigate to the root of the new project and run the command: mvn

**** Right now this creates all of the files, etc. but there is still a bug preventing it from totally compiling for me ****** more once I get that bug fixed!