Is it possible to upload a Java Elastic Beanstalk application through the command line tools for EB?
I know that I can upload my application to EB via the web console (uploading the WAR file) or by using AWS's instructions for Eclipse. However, I also want to see if I can use the AWS DevTools to upload updates to my app to EB. I have already used the eb command-line tool to create and configure my git repository for my application, so I can use the git aws.push command. However, no matter what I try (push my entire workspace, push a repo with just the war file, push a repo with the contents of the exploded war file contents as described in this blog post), it never works. A .zip file is uploaded to Beanstalk and my application becomes unhealthy.
I began to wonder if git aws.push is only available for PHP apps and not Java, since PHP is the only language mentioned in AWS's documentation for the DevTools. Anyone have any idea if git aws.push is available for Java apps?
BTW, I should mention that my .war file was created by using mvn clean install, since my application uses a Maven-based workspace. I am aware of the Maven Beanstalker Plugin that I could possibly use for uploading the app to Beanstalk, but nonetheless, I still want to see if git aws.push is available to me.
Related SOF post: Deploying Java web application to Amazon Elastic Beanstalk
AWS Elastic Beanstalk expect Zip Files (and war files are zip files) containing the source files (when using scripting languages) or binary content (.NET and Java) as Available Versions
Beanstalker takes advantage to this via fast-deploy, which takes the war file contents (from target/${build.finalName}), copies to a temporary directory (tmp-git-staging), then calls the AWS EB Endpoints. It is notably reliable, even if AWS itself didn't document the interface.
It picks up, builds a .s3 file and optionally calls an UpdateEnvironment to this new version label.
RE aws.push:
aws.push creates an URL to an authenticated AWS EB endpoint for git, and then calls git push. The code to use is similar to this one
Related
I think it can divide as three steps:
list only changed .class
upload them to sftp server
restart server
I can do 2. and 3. with wagon-maven-plugin, but I don't know how to do 1. with the wagon-maven-plugin.
some background:
This is a very old project(spring 3.x), plain spring web project without any maven stuff and running on tomcat server.
Our current deploy way is:
build project with IntelliJ IDEA
manually upload changed .class files to server via sftp
restart tomcat server with ./shutdown.sh and ./start.sh script.
I want improve the deploy way, because it's error-prone when we choose which files need to upload and I can't just upload all the class because it may overwrite other people's work.
I know we should just use jar/war format, but because history reason we can't.
I have followed this very basic tutorial for setting up a WebSocket endpoint in Java: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html
Heroku, however, expects me to rely on Play Framework: https://devcenter.heroku.com/articles/play-java-websockets
My question is: how could I deploy the same without any additional frameworks and what procedure should I go through in order to make things work?
The problem you had was this:
The tutorial you followed was made for the GlassFish Application Server but Heroku only supports Tomcat 8 and Jetty. See here: https://devcenter.heroku.com/articles/war-deployment
But don't worry, I ported and tested the tutorial to run with Tomcat 8.
I also added the glassfish implementation of the javax.json specification.
(Make sure to download the implementation and not the spec interfaces only)
You can find it here: http://central.maven.org/maven2/org/glassfish/javax.json/1.0.4/
I also noticed why maybe your index.html didn't work locally: I think it was because the WebSocket URL was hardcoded in the websocket.js file.
I have taken the liberty to fix this by making it dynamic.
Here is the complete NetBeans 8.0.2 project:
http://ray.hulha.net/WebsocketHome.zip
Here is the best way to create a war file from inside NetBeans 7 or 8:
There is one catch however, the Tomcat 8 on Heroku is missing the websocket addon.
But no worries, you can added it manually to the war file.
Here are the steps:
Download the Tomcat websocket addon here:
http://central.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-websocket/8.0.29/tomcat-embed-websocket-8.0.29.jar
The war file is really just a zip file. So I used 7-zip to open the war file. Then navigate to the WEB-INF/lib folder inside the war file.
Copy the jar into the war. Drag and Drop the tomcat-embed-websocket-8.0.29.jar into the lib folder of the war file inside 7-Zip.
Z-Zip will ask if you really want to copy the jar into the war file.
Say Yes.
Here is the compiled war file complete with the tomcat-embed-websocket-8.0.29.jar ready to deploy on Heroku:
http://ray.hulha.net/WebsocketHome.war
I used this command to deploy it:
heroku war:deploy WebsocketHome.war --app websockethome
Make sure to replace the app name in the end with your app name.
And here is the working result:
http://websockethome.herokuapp.com/
Heroku does not require Play framework to use Websockets. That is just an example. As long as your app from the Oracle tutorial binds to $PORT it should work.
I am trying to deploy a war file in tomcat7. I am using MySQL JDBC driver to connect to database server. The jar file of MySQL JDBC driver is copied to $CATALINA_HOME/lib/ directory and the web application works correctly.
Now, I want to deploy the .war file in Amazon Elastic BeanStalk service. By default, Amazon doesn't place the MySQL JDBC driver in $CATALINA_HOME/lib directory by default and I can't run a script which will ssh into each instance and download the jar in the directory.
Is there any way, in which I can bundle the jar file for JDBC driver , so that I don't have to download and place the jar file in $CATALINA_HOME/lib directory ?
You can place the jar file in an S3 bucket, and then use a EB container command to copy the file to the lib directory, like:
"copy-lib-file":
mode: "000644"
owner: root
group: root
source: https://s3.amazonaws.com/<MY_BUCKET>/<my-JDBC-driver>.jar
No you can't bundle JDBC JARS for Tomcat7:
I've had this issue and it was a nightmare to debug. In my trials and in the documentation you can't bundle JDBC drivers inside your WAR file. Or at least you can but the classloader will ignore JDBC classes that are not in the Tomcat Lib folder. Its in the first paragraph of the Mysql section of the documentation here -> Tomcat7-JDBC I don't know of Tomcat8 or Tomcat9 beta...
Short Term Solution
What I do is exactly what you said you don't want to do and similar to Mark B's solution. I use a script that copies it from s3 but this is really easy and is only 1 line of bash if you use the aws s3 cp command. The aws s3 tool comes installed on the EC2 instance your application will be running on.
aws s3 cp s3://mybucket/mysql.jar /usr/share/tomcat7/lib/mysql.jar
*You will need to restart tomcat another reason you should see the longterm solution
Long Term Real Solution = Automate Your Build Steps
In the end you'll eventually have to run provisioning scripts if your application becomes complex, which is why I stopped using elastic beanstalk and started using AWS cloudformation which gives you a "STEP" where you can throw in all your setup scripts similar to docker build steps. It will also run those configuration steps for every new instance that gets created so there is no needed for you to ssh onto every box.
Cloudformation is all about turning your infrastructure setup into code which you could actually check into github and build without any manual intervention. You go through the headache of configuring your build scripts once then save your environment as a json or yaml file. You can include the MySQL server, tomcat version, firewalls, load balancers etc etc and build that all from a file.
Tomcat, like many application servers, installs a variety of class loaders (implementation of java.lang.ClassLoader) that will give your application access to the JDBC jar resource.
The order is:
Bootstrap
System
Common - $CATALINA_BASE/lib
Webapp - /WEB-INF/lib
Put the jar into the WEB-INF/lib directory inside the application. Note, this JAR will be only visible to this specific application and no others.
In order to do so you need to use .ebextensions.
With .ebextensions you can copy files from your application package to the beanstalk file system.
However keep in mind that no other application deployed in a beanstalk environment will use your driver. Your beanstalk instance is dedicated to one application. Every time you upload the application you have to upload the mysql driver in order to be deployed to the tomcat installation.
Therefore you do not gain anything in terms of upload size or memory footprint in a tomcat (shared jdbc connetion pool through jndi).
It seems that uploading your application with the jdbc driver included (non provided in your maven config) is a more beanstalk oriented solution.
However there are cases you don't want to make any changes in the way your war gets packaged, for example your application gets deployed to an on premises tomcat server containing the jdbc driver and you want to upload it to an elastic beanstalk environment.
In such cases you can consider docker with elastic beanstalk as an option too.
Is there a way to specify if the java source files are included in the WAR file when deploying through eclipse?
Please consider the following scenarios:
Using export to war: This is simple and straight forward. If you check the check box marked "Export source files", then the source files are included in the WAR.
Publishing to the local Tomcat server: The source files are never included in the wtpwebapps directory and there is no WAR file. Again, simple.
Publishing to Elastic Beanstalk through the eclipse AWS toolkit on a Windows machine: The source files are ALWAYS included with the WAR file (which is exploded into the git folder and then deployed as a Zip file).
Publishing to Elastic Beanstalk through the eclipse AWS toolkit on a Linux (Ubuntu) machine: The source files are NEVER included with the WAR file which is eventually deployed.
I have not found a way to stop the source files from being included in 3 or include them in 4. This may well NOT be an OS issue, but a simple setting in some configuration file that is set differently on the two machines. Or it could be the way the plug-ins were written for the two Operating Systems (are plug-ins OS specific?). Even if that's the case, is there a setting where it can be changed?
I tried playing with the Web Deployment Assembly settings, but couldn't figure out how to make that work as far as source is concerned.
Any insight you may have into this will help.
As the question explains I want to deploy a Java servlet based application which is developed on a local server (Apache Tomcat 6.0). I have the IP address, Host name for the new virtual server. I want to know, if it will be just a normal site migration process where I'll have to install Tomcat on the new server and configure the server, web XML files or is there a bit more.
As I have not done Tomcat config before. Any Help would be great
Is there a step-by-step documentation to perform this
Thanks
Download and install Java
Download Tomcat http://tomcat.apache.org/download-70.cgi
Read http://tomcat.apache.org/tomcat-7.0-doc/setup.html
Build your webapp into a war file with your build scripts
Copy the war file into webapps directory under your tomcat installation directory. More details can be found http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html
I find it best to create a script that deploys my webapp from running my build script. And scp and ssh task comes in handy for installing it quickly. There are probably other maven tasks that might work for you.