The assembly process for ATG applications can be complicated to setup and very slow. Every ATG installation comes with an executable, runAssembler, to aid in assembling applications. The runAssembler executable has a plethora of options and it is critical to know when to use each. Additionally, since ATG applications consist of many individual modules, it’s important to know how to properly order the modules. ATG’s concept of ‘configuration layering’ starts with the correct module ordering in the final assembled application. Mastering the assembly of ATG applications is beneficial for every project. In this guide, I’ll use the ATG documentation and personal experience to provide the best overview on assembling ATG applications.
Disclaimer: I did not come up with everything in this document. Some is copied from the ATG Programming Guide.
For a complete reference of runAssembler arguments, see the ATG Programming Guide.
Using runAssembler
runAssembler can be found in $DYNAMO_HOME/bin. For windows, it’s a batch file, while *nix will be an executable. The basic usage is:
$DYNAMO_HOME/bin/runAssembler(.bat)[-liveconfig] /path/to/ear/filesname.ear [-additional options] [-layer layer-name] [-standalone] -m [space-separated-module-list]Here are the most relevant runAssembler arguments you’ll use on a daily-basis:
Argument Info -liveconfig This flag instructs the application to use a special layer of configuration only appropriate for production environments. This needs to be the first argument after runAssembler. -overwrite Use this to completely overwrite the previous ear file. By default, only the newest files are overwritten and the unchanged are unchanged. -pack By default, ATG ears are assembled into ‘exploded’ directory. This option packs the ear down into an ear file. -server [server] If you’re building out an ear for a specific server, i.e publishing or storefront etc, you can include the ATG server name to include a server-specific configuration layer. These are the servers that will be in $DYNAMO_HOME/servers. -standalone This must be after the -layer flag and before -m flag. This puts everything required into the ear file and does not refer back to the ATG installation at runtime (much preferred in a production environment). Without this, configuration isn’t included in the ear, but instead referenced from the ATG installation. -m <module-1 module-2..> A list of modules to include in the application. This is very important and will be discussed further down. Solving Development Problems with runAssembler
To help understand when these would be appropriate, learn from some problems a developer could face:
Problem
The size of your ear file is really big. It’s becoming a pain to move around.
Solution
Assemble it with the -pack flag. Instead of having an exploded directory, you’ll have a single ear file with a good degree of compression.
$DYNAMO_HOME/bin/runAssembler -pack -overwrite $JBOSS_HOME/server/crs_prod/deploy/crs-demo.ear -m <module-list>Problem
You want to include server configuration into your application. For example, you’re working on the BCC and you want to build out an ear with all the configurations needed only for a publishing server.
Solution
Use the -server <server-name> flag where ‘server-name’ matches with a server in $DYNAMO_HOME/servers. That server’s local config layer will be included into the config path.
$DYNAMO_HOME/bin/runAssembler -overwrite -server css_prod $JBOSS_HOME/server/crs_prod/deploy/crs-demo.ear -m <module-list>Problem
It’s time for production and you need to build an application on one server, then distribute it onto multiple servers for production hosting.
Solution
Use the -standalone flag to assemble the application with all the required resources included in the final ear file. The file will be significantly larger, but it will contain all the resources needed to run the application in a foreign environment (no ATG installs required).
$DYNAMO_HOME/bin/runAssembler $JBOSS_HOME/server/crs_prod/deploy/crs-demo.ear -standalone -m <module-list>Assembling ‘big’ ear Files
If your project spans multiple servers types, i.e storefront, publishing, CSC etc, it becomes cumbersome to assemble ears for each server. It is much easier to build one ear with everything needed to run the application from all fronts, then select which parts need to be run. This special type of ear is typically called a ‘big’ ear.
The process for building a big ear is just like building a standard ear, but with a few tweaks:
1. Don’t use the -server flag. The -server flag includes a specific server configuration into the ear. Including configuration for a CSC server would not make sense if the app was also running a publishing and storefront server. To get around this, starting the server with the atg.dynamo.server.name command line argument does the same thing -server would do.
$JBOSS_HOME/bin/run.sh -c css_prod -Datg.dynamo.server.name=crs_prodThis would startup my ‘crs_prod’ server with the ‘crs_prod’ ATG server configuration included.
2. The module ordering needs to be correct. Assembling a single application is easy because there is only one module ordering. Assembling multiple applications that have their own module ordering into a single ear requires some thinking. Just because you’ve combined all the modules from each individual application and added them into a single list doesn’t mean everything will work. It will take some experimenting.
Using atg.dynamo.modules
Trying to run a big ear without limiting the modules that start will cause problems with the application. Even though you may try starting the big ear on your publishing server, the other parts of it will try to start too (CSC, storefront etc). The solution is using the atg.dynamo.modules command line argument. By listing out the modules required by each server instance in atg.dynamo.modules in the configuration for each server, you can build an ear with all the required modules and delegate which to start on each server.
$JBOSS_HOME/bin/run.sh -c css_prod -Datg.dynamo.server.name=crs_prod -Datg.dynamo.modules=Module1,Module2,Module3This would startup the ‘crs_prod’ JBoss server and only Module1,Module2,Module3. No matter what other modules were included in the build, only Module1-3 will start.
Note: on windows the module list would need to be separated by a semi-colon (;).
Module Ordering
Module ordering is really important in the ATG application assembly process because it plays into which configurations and classes will overlap each other. When assembling ATG applications with runAssembler, the module list is everything after the -m flag.
Here’s an example of how the application assembler uses the module ordering to assemble the application:
[runAssembler args] -m DafEar.Admin,DPS,DSS,B2CCommerce,DCS.PublishingAgent,DCS.AbandonedOrderServices,Store.Storefront,Store.EStore.International,Store.Storefront.NoPublishingThere is a complicated algorithm that runAssembler uses to gather classes and configuration. For all practical purposes, remember this one thing: modules the appear later in the list will override modules that appear before them. Notice how the custom modules (Store.Storefront.NoPublishing,Store.Estore.International…etc) are the last ones on the list? This ensures that their configuration and classes will come before any base ATG modules.
The first thing runAssembler does when evaluating module dependencies is inspect the manifest. Manifest’s with ‘ATG-Required’ and ‘ATG-Required-If-Present’ attributes determine if any modules need to be loaded before the current module. To see each dependency get pulled into the assembly, see runAssembler’s output:
After evaluating the list of modules and coming up with a final list of modules, the class files of each are put into the atg_bootstrap_ejb.jar file of the final ear. This is the application’s classpath and it does not change. The final classpath of your application will be printed out at startup. Here’s the classpath of our example:
Another important thing to remember about the ATG assembly process is that the config path is not determined until runtime. At runtime, the NucleusServlet inspects the module ordering and sets the config path.
You can see from our example config path that it follows closely the module ordering of the assembly arguments above. There may be extra configuration layers added on because of unseen dependencies.
Added-On ATG Config Directories
Notice how the last two items in the config path aren’t modules, but just configuration directories. Out of the box, ATG will add the $DYNAMO_HOME/localconfig directory onto the end of the config path. If some configuration needs to be changed very quickly, it can be put into the localconfig directory. Try to not depend on localconfig for much configuration. To change the localconfig directory of the application, modify the ‘dataDir’ setting for the ear:
$JBOSS_HOME/bin/run.sh -c crs_prod -DdataDir=/foo/bar/ATG_ConfigThis would start the server with the /foo/bar/ATG_Config directory enabled as the localconfig layer. This is not the only way to set this setting.
The last block of information that NucleusServlet will output will be a list of the ATG environmental variables set. This is often useful for diagnosing assembly errors.This last configuration layer in our example is the configuration for the server. This configuration will only be there if the application has been assembled with the -server flag, or the atg.dynamo.server.name variable is pointing to a dynamo server.
Jonny,
What options are you passing to run assembler when you are assembling the application?
Where is the assembly stalling, is it at the step where it imports config + java, or at the j2ee import step?
Have you verified the issue is only in the assembly step?
we are running into a issue without local development in windows where the assembler takes 10 times as much time as it would take on our build servers. Our local windows pcs have i7s with 24 gig ram. and while this process is running memory and cpu are not taxed. any ideas ?
Great Work
Lokivog,
I don’t want to give away all the secret sauce here, but we strongly believe in being able to use the same EAR in any environment. Our approach is probably closest to #3, however we don’t use (or like) environment modules. Environment specific settings should be managed separately from code development, and often by a different team (for ops or PCI reasons).
Devon
Great article, although I was wondering how sparkred prefers assembling the ear and managing server and instance level component configuration settings for large scale ATG applications. I have seen 3 different approaches:
1. Using ATG Configuration Groups
2. Customizing the build and deploy scripts to pull in the correct server instance configs
3. Creating an environment module that contains all instance configurations and use the -Datg.dynamo.modules and –layer flags to startup the correct instance module and layer
Great article. Thanks a lot for this post.