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.
Related
I am having trouble connecting to the endpoints of my java application deployed to AWS Elastic Beanstalk. The application handles a number of POST requests and is intended to serve a mobile application, so the server itself does not have any static files. I used the Spark Java framework, which finds the endpoints correctly when I test on Localhost, but not on AWS Elastic Beanstalk.
I can deploy the Exploded war onto EB (running Tomcat Web server), yet all requests that I send return a 404 Error: Resource not Found. Spark java runs on the embedded Jetty server, so to run on Tomcat, I did as suggested in their documentation (http://sparkjava.com/documentation#other-web-server): I have implemented the SparkApplication interface, moving all endpoints from main() to init() and I added the suggested code to the web.xml file.
The .war uploaded contains META-INF with web.xml, lib (with the gradle libraries), and classes (with my compiled output). Again, no static files.
More details:
I use the Elastic Beanstalk IntelliJ (Ultimate) plugin to deploy and at this point I tested that this is no different from deploying a .war directly on the EB dashboard. I have opened to all ports and connections in security settings to discard any connectivity issue. I believe this is just a matter of the servlet not mapping the urls. Any suggestions?
Run it as a war on local box to make sure you have the wiring right. I have done this recently - Spark Java on Beanstalk, but I think I deployed it as a jar. Beanstalk supports just straight java jar (fronts it with nginx). I think when I deployed as a jar, I did have to do something to specify the listening port of 4567 that Spark Java uses by default.
I have run Spark Java as a war in Tomcat as well, but I don't think on AWS - I believe in that case I deployed as a jar.
Solved! I had code inside the main class that was changing the port. While this was necessary to run on the local environment, it conflicted with AWS, which assigns the port automatically.
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
I am developing a web application and have hit a wall and could use some advice. So the application was written by a coworker who is no longer at our company. They wrote a web application for Apache Tomcat with Java and Javascript in the back end. The application makes use of the JDBC api to interface with a SQL Server database. This person did all the development in Eclipse and running it this way.
I am trying to take this web application and move it to a server. I attempted this by using Eclipse to export a WAR file and then placing this within the Tomcat webapps folder. Then when I started Tomcat the program was extracted. So far so good. The website comes up and works well. However, when I try to access the pages which rely upon database info everything is coming up NULL. I went through the Tomcat logs and found that in the standard out the following message was given:
ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
I had assumed that the WAR file would include all dependencies but I am guessing that probably this is not the case. If anyone is experienced, is this what has happened? If anyone out there is aware, is there a way to tell Eclipse to do this? Otherwise, what is my option? I am not a Java dev and so I would not know how to install JDBC if needed.
Any help is appreciated.
Mike
You can do the following
Go to Microsoft JDBC Driver download page and download the JDBC driver and install it to a location.
Open the .war file using a zip utility like 7-zip or winzip.
Copy the sqljdbc.jar from the sqljdb_4.0/enu directory where you installed the downloaded JDBC driver and paste it in WEB-INF/lib of the extracted war file.
Zip it back as .war file and deploy it again.
This will get the application running.
If you want to fix this permanently, then you should add the stop to include sqljdbc.jar to your WEB-INF/lib while building war file, in your build system, i.e. in build.xml if you are using ANT or in your Maven's pom.xml under dependencies section for this particular dependency.
You don't need to do the "Export WAR > copy to tomcat > start tomcat" manually, you could configure eclipse to do the deploy directly in your tomcat installation, firts double click tomcat server, and then select "Use tomcat installation" in the "Server Locations" section.
Make sure that your application contains the SQLServer JDBC driver (sqljdbc4.jar) in your project WebContent/WEB-INF/lib directory (assuming your coworker used the Eclipse "Dynamic Web Project" for the project layout), if not, download from here, unzip and copy it to the mentioned folder, the next time you start tomcat, it will automatically add it for you.
If the project uses the maven project layout (there is a file named pom.xml in the project root folder), use the following instructions to install the dependency in your local repository (there are some disagreements between Maven and Microsoft about licensing and redistribution of the driver, so there is no repo)
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.
We have a couple of JBoss instances using the same JBoss installation and would ask if its possible to declare a datasource(or JMS connection factory) in one location that will be available to all instances.
If you have one data source definition and just you want to install it on all servers you can use one of these methods:
Use RHQ platform to monitor your JBoss server and deploy new application (and also data sources)
Use twiddle command (you can find in your JBoss bin directory) and MainDeployer bean:
twiddle invoke "jboss.system:service=MainDeployer" deploy /some/path/myapp.ear
Just remember that your data source should be accessible from server and will not be install after server restart - after each JBoss restart you need to tun these twiddle command. More info: Application Deployment
If your JBosses servers works in cluster you can try and use farm directory: Farm Management.
You can use SSH (or maybe FTP) server and copy the data source on each location. scp command can be very useful when you connect it with login by keys.
You can create some directory and export it by NFS. Than mount on each machine that directory and tell JBoss to deploy application from it. More info: How to deploy my application in an external directory in JBoss-5.
You can access the data source configured in one instance out side that instance. Check http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/beta500/html/ch13s15.html. Is this what you are looking for?