Page 1 of 1

Embedded Tomcat does not work on Amazon AWS

Posted: Sat Nov 17, 2012 3:31 pm
by chico1198@yahoo.com
Recently I began migration of the demo app to Amazon AWS. (I wanted to make sure migration worked before putting in major development time.) Almost everything was a breeze, except getting the correct JBDC connection string. But, after studying the way Amazon configures RDS that was not much of an issue. (BTW, when I get the app working, I plan to put a HOW-TO on the forum.)

When I finally got my connection string correct, I realized I had (at least) one more issue - the demo's embedded Tomcat configuration vs. running Tomcat on a server. The demo will not run with the project's out-of-the-box settings on AWS! Here's how I figured this out:

If you look at the suggested Ant task in the Broadleaf documentation, the writer suggests that you use an embedded version (this is a copy/paste from the documentation)

Code: Select all

<target name="tomcat-demo" depends="start-db">
    <delete dir="war/WEB-INF/lib"/>
    <artifact:mvn mavenHome="${maven.home}" fork="true" jvmargs="-DbroadleafCoreDirectory=${broadleafCoreDirectory} -DbroadleafWorkspaceDirectory=${broadleafWorkspaceDirectory} -XX:MaxPermSize=256M -Xmx512M">
        <arg value="compile"/>
        <arg value="war:exploded"/>
        <arg value="tomcat7:run-war"/> <!-- this is the command to run embedded -->
    </artifact:mvn>
</target>

During development I once made the mistake of running the instance in server-mode (i.e. <arg value="tomcat7:run"/>) and got the following error.

Code: Select all

[ERROR] 09:19:28 ContextLoader - Context initialization failed
[artifact:mvn] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in resource loaded from byte array: Cannot resolve reference to bean 'blPersistenceUnitManager' while setting bean property 'persistenceUnitManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'blPersistenceUnitManager' defined in resource loaded from byte array: Invocation of init method failed;

I realized my mistake and changed it back to embedded-mode (i.e. <arg value="tomcat7:run-war"/>). All was good. I thought of trying to figure out why the project did not run in server-mode, but running in embedded-mode solved the problem so I moved on.

Now I have deployed the application to Amazon AWS and, guess what?, I get the same error message! I guess I now have to figure out why the demo will not run in server-mode. Any ideas on what project settings need to change to run the demo in Tomcat7 server-mode vs. the documented embedded-mode? Thanks.

Re: Embedded Tomcat does not work on Amazon AWS

Posted: Sun Nov 18, 2012 2:39 pm
by jefffischer
Hmm - haven't tried tomcat7:run. I know we run the demo all the time in a regular standalone tomcat7 instance. Have you tried building the war and manually deploying it to a standalone tomcat instance?

Re: Embedded Tomcat does not work on Amazon AWS

Posted: Sun Nov 18, 2012 11:52 pm
by chico1198@yahoo.com
I just tried that - and it worked! Now I am just stumped. Why would it work locally and not on Amazon? I am passing the same parameters, etc. Here is the local start-up command and response:

Code: Select all

C:\apache\apache-tomcat-7.0.32\bin>startup -DbroadleafCoreDirectory=${broadleafCoreDirectory}" -DbroadleafWorkspaceDirectory=${broadleafWorkspaceDirectory}" -XX:MaxPermSize=256M" -Xmx512M" -Druntime.environment=production
Using CATALINA_BASE:   "C:\apache\apache-tomcat-7.0.32"
Using CATALINA_HOME:   "C:\apache\apache-tomcat-7.0.32"
Using CATALINA_TMPDIR: "C:\apache\apache-tomcat-7.0.32\temp"
Using JRE_HOME:        "C:\glassfish3\jdk7"
Using CLASSPATH:       "C:\apache\apache-tomcat-7.0.32\bin\bootstrap.jar;C:\apache\apache-tomcat-7.0.32\bin\tomcat-juli.jar"
C:\apache\apache-tomcat-7.0.32\bin>

Two things I noticed, 1) that the stand-alone version seemed not to read the 'production' flag correctly, (Should that be in quotes?) and 2) the embedded SSL cert that I use in the stand-alone version seems not to work here as Tomcat looks for it on start-up. (Can I just put my self-cert into the correct Tomcat directory to fix that?)

Ideas on getting it to work on Amazon AWS?

Re: Embedded Tomcat does not work on Amazon AWS

Posted: Mon Nov 19, 2012 12:28 am
by chico1198@yahoo.com
I managed to solve the second of my two problems, the SSL cert. It seems that Tomcat7 has a peculiarity that you need to comment out a line to get it working. The symptom was:

Code: Select all

SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-apr-8443"]
java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR

The following source provided the answer I needed: http://stackoverflow.com/questions/10545922/issue-in-tomcat-7-0-to-configure-tomcat-to-support-ssl

That said, I am down to one issue running stand-alone and then my "real" problem, running on Amazon AWS. Can you shed any light on why the app does not recognize the 'production' attribute?

I'll take up the operation of the app with Amazon in the morning. ;)

Re: Embedded Tomcat does not work on Amazon AWS

Posted: Tue Jan 15, 2013 5:44 am
by sraemy
I've just gone throught the process of installing the shop in the AWS Elastic Beanstalk. Here are a couple of infos that might help:

- You need at least a m1.small instance (64bit/Tomcat7) (I've tried the micro without any success), I set the PermGenSpace to 128m and used the -server option for tomcat

- You need to enable SSL in your elastic beanstalk environment configuration. Therefore, install the SSL certificate in IAM (http://stackoverflow.com/questions/12791244/how-to-automatically-install-an-ssl-cert-on-an-aws-elasticbeanstalk-running-on-w). My approach was setting up a micro EC2 instance and install the iamcli package (the aws.properties file mentionned below contains the AWS access key and AWS access key id):

Code: Select all

AWSAccessKeyId=<your secret key id>
AWSSecretKey=<your secret key>

Install the package with:

Code: Select all

apt-get install iamcli

Then you can install the certs with the following tool:

Code: Select all

iam-servercertupload

and finally you list your installed certs with:

Code: Select all

iam-servercertlistbypath --aws-credential-file ./aws.properties

The corresponding key goes into the SSL cert identifier of your environment configuration

In AWS there are a couple of environment variables you can configure in the environment configuration. Namely: AWS_ACCESS_KEY_ID, AWS_ACCESS_KEY, JDBC_CONNECTION_STRING, PARAM1, PARAM2, PARAM3, PARAM4 and PARAM5 I believe
- I decided to use PARAM1 to inject the environment info into the application. Therefore i had to modify the PropertyKeyResolver once in the admin and TWICE in the site app. Here's my config:

Code: Select all

<bean id="blConfiguration" class="org.broadleafcommerce.common.config.RuntimeEnvironmentPropertiesConfigurer">
  <property name="keyResolver">
    <bean class="org.broadleafcommerce.common.config.SystemPropertyRuntimeEnvironmentKeyResolver">
      <property name="environmentKey" value="PARAM1" />
    </bean>
  </property>
</bean>

- To resolve the JDBC connection string (containing all the connection info including the user and password), I've used the standard Spring mechanism to resolve system properties:

Code: Select all

<bean id="webDS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="#{systemProperties['JDBC_CONNECTION_STRING']}" />
</bean>

- Use the same mechanism if you want to inject the baseURL of an external SOLR server if needed.
- Make sure your Elastic Beanstalk security groups are configured in your RDS security group (also it's important to remove them before deleting the env/app ;) )

There might be more steps, but i hop this helps already.