Netbeans: deploying Java app to remote Tomcat - netbeans

Is there any easy way to automatically deploy a web service / java web app, etc to a remote tomcat server? currently i have to manually copy the .war file.

Personally, I add a "deploy" target in build.xml that contains an <scp> tag to transfer the war file.
UPDATE:
Here is an example:
<target name="deploy" depends="dist">
<scp todir="${user.name}#www.myserver.com:tomcat-base/webapps/"
keyfile="${user.home}/.ssh/myserver.key"
passphrase="BlaBlaBla" trust="true">
<fileset dir="dist" includes="myapp.war"/>
</scp>
</target>

Related

How to speed up Alfresco Share development

I'm developing and performing some customization on Share. My IDE is Eclipse Juno and workspace is made up of the next elements:
alfresco web project
extensions Java project
share web project
Both alfresco and share web projects are deployed in separate Tomcat instances, this way I can slightly speed up my development tasks by restarting only the Tomcat instance where Share is deployed.
My extensions Java project has the same structure as the Eclipse project proposed by Alfresco. Y the provided Ant tasks for compiling, compressing JavaScript files, packaging and deploying the resultant JAR file in Tomcat.
I'm developing some new JavaScript client-side widgets, which means every time I make a change I have to stop Tomcat, launch Ant build script and start again so as I have to do it very often, you can guess what a pain it is becoming. I was just wondering if there exist any way to speed up development tasks on Share. How do Alfresco developers team do it? What kind of environment do they set up?
I was thinking about creating a new Ant target which hot deploys extension project's content into deployed Share web project, taking into account paths of course; that mechanism must allow the reverse operation by the way. Would that be viable? The idea would be to have a similar deploy mechanism as when you develop regular web projects: when you make any change you just push the "Publish" button and the changes are populated into the server.
I would like to know some tips and ideas, specifically from Alfresco developers team if possible.
PS: I have already read https://forums.alfresco.com/en/viewtopic.php?f=47&t=44850 and https://forums.alfresco.com/en/viewtopic.php?f=48&t=18749.
Two things that speeds up things a lot:
Invest in a jrebel license for class reloading without server restart http://zeroturnaround.com/software/jrebel/
Construct ant tasks that copy webscripts to the target folder and reloads webscripts with curl if necessary.
Example of a task that reloads an Alfresco Share webscript:
<target name="deploy-share-webscripts" depends="Share: Copy files" description="Refreshes the list of webscripts">
<exec executable="curl">
<arg value="-d"/>
<arg value="reset=on"/>
<arg value="http://admin:admin#${share.web.url}/page/console?reset=webscripts"/>
</exec>
</target>
Appending the copying part of the ant task (the src-dirs are declared as properties in the beginning of the buildfile):
<echo message="- Copying java classes" />
<copy todir="${warWebappTargetClasses}" overwrite="false" verbose="true">
<fileset dir="${warTargetJavaDir}" />
</copy>
<echo message="- Copying resource files" />
<copy todir="${warWebappTargetClasses}" overwrite="false" verbose="true">
<fileset dir="${warSrcResourcesDir}" >
<include name="**/model/*"/>
<include name="**/templates/**/*"/>
<include name="**/custom-model-context.xml"/>
<include name="**/web-client-config-custom.xml"/>
<include name="**/webclient.properties"/>
<include name="**/aka-model-resourcebundle*"/>
<include name="log4j.properties"/>
</fileset>
</copy>
<echo message="- Copying resource files from amp into war for quick deployment." />
<copy todir="${warWebappTargetClasses}" overwrite="false" verbose="true">
<fileset dir="${projectAmpResourcesSrcDir}" />
<fileset dir="${projectAmpClassesDir}" />
<fileset dir="${listmanagerAmpResourcesSrcDir}" />
</copy>
<echo message="- Copying config files from amp into war for quick deployment." />
<copy todir="${warWebappTargetClasses}\alfresco\module\Project-amp\" overwrite="false" verbose="true">
<fileset dir="${projectAmpConfigSrcDir}" />
</copy>
</target>
I use the maven alfresco lifecycle http://wiki.alfresco.com/wiki/Managing_Alfresco_Lifecyle_with_Maven for my setup, which also speeds up things. I sure a lot can be added to this topic.
You can avoid copying the webscripts to the tomcat by configuring additional paths for tomcats shared classloader. This is a setting in tomcat/conf/catalina.properties. I set this directly to the projects source directory so there is no need for the compile step.
shared.loader=${catalina.home}/shared/classes,${catalina.home}/shared/lib/*.jar,\
/path/to/my/dashlet/src/main/resources,\
I also have the following settings in shared/classes/alfresco/web-extension/share-config-custom.xml to enable automatic refresh of templates and webscripts.
<alfresco-config>
<!-- Global config section -->
<config replace="true">
<flags>
<!-- Developer debugging setting - DEBUG mode for client scripts in the browser -->
<client-debug>true</client-debug>
<!-- LOGGING can be toggled at runtime when in DEBUG mode (Ctrl, Ctrl, Shift, Shift).
This flag automatically activates logging on page load. -->
<client-debug-autologging>false</client-debug-autologging>
</flags>
</config>
<config evaluator="string-compare" condition="WebFramework">
<web-framework>
<!-- Autowire Runtime Settings -->
<autowire>
<!--
Developers can set mode to 'production' or 'development' (to disable; SpringSurf caches,
FreeMarker template caching and Rhino JavaScript compilation.)
-->
<mode>development</mode>
</autowire>
</web-framework>
</config>
</alfresco-config>
Well this is the solution that is working 100% as I expected. I came up with this after the answers of #erik-b and #jorn-horstmann and taking into account some posts I have read.
So basically I have the next Ant target which hot deploys the content of my Share extensions Java project:
<!--
Hot copy individual files into appropriate deployment folder (e.g. $TOMCAT_HOME/webapps/share)
-->
<target name="hotdeploy-tomcat-share" depends="clean, prepare, build-jar" description="Hot copy individual files into appropriate deployment folder (e.g. $TOMCAT_HOME/webapps/share)">
<echo message="Generating and deploying JAR file with custom configuration files" />
<jar destfile="${dist.dir}/${jar.name}">
<!-- Only including configuration XML files such as share-config-custom.xml -->
<fileset dir="${build.jar.dir}" includes="**/META-INF/*.xml" />
</jar>
<copy todir="${tomcat.share.deployment.path}/WEB-INF/lib">
<fileset file="${dist.dir}/${jar.name}" />
</copy>
<echo message="Hot deploying Share files" />
<copy todir="${tomcat.share.deployment.path}/WEB-INF/classes" includeEmptyDirs="false">
<fileset dir="${build.jar.dir}">
<patternset refid="hotdeploy-tomcat-patternset" />
</fileset>
</copy>
</target>
Auto-reloading modules feature must be disabled, otherwise every time you execute the above Ant target Tomcat will reload Share and other web apps deployed. Additionally, I believe it is also possible to hot deploy in the $TOMCAT_HOME/shared/ directory but I haven't tried it out yet.
The Java project I'm using for developing my extensions is this model project: http://code.google.com/p/share-extras/wiki/SampleProject. There is the full build script with the other targets required.
I'm also using this in my share-config-custom.xml:
<!-- Global config section -->
<config replace="true">
<flags>
<!--
Developer debugging setting to turn on DEBUG mode for client scripts in the browser
-->
<client-debug>true</client-debug>
<!--
LOGGING can always be toggled at runtime when in DEBUG mode (Ctrl, Ctrl, Shift, Shift).
This flag automatically activates logging on page load.
-->
<client-debug-autologging>false</client-debug-autologging>
</flags>
</config>
<config evaluator="string-compare" condition="WebFramework">
<web-framework>
<!-- SpringSurf Autowire Runtime Settings -->
<!--
Developers can set mode to 'development' to disable; SpringSurf caches,
FreeMarker template caching and Rhino JavaScript compilation.
-->
<autowire>
<!-- Pick the mode: "production" or "development" -->
<mode>development</mode>
</autowire>
<!-- Allows extension modules with <auto-deploy> set to true to be automatically deployed -->
<module-deployment>
<mode>manual</mode>
<enable-auto-deploy-modules>true</enable-auto-deploy-modules>
</module-deployment>
</web-framework>
</config>
The last XML snippet avoids to refresh webscripts after any change performed on an FTL page, for example.
I have also performed some tests with JRebel but after my experience I would say it doesn't helps a lot in Share development.
There is also interesting stuff in the next articles:
http://blogs.alfresco.com/wp/kevinr/2010/04/07/developer-tips-for-alfresco-share-33/
http://techblog.zabuchy.net/2012/debugging-javascript-in-alfresco/
Hope it helps others.
I'm usually working on private instances so I can afford myself to run exploded apps, so any changes are visible immediately for me. I only need to restart tomcat when I change the datamodel, deploy some new java-backed modules or webscripts or similar. Even though some of those can get reloaded live too.

Cleaning Deployment Assembly with Eclipse Plugin

When faced with the unenviable task of cleaning all generated project artefacts/resources in a stock-standard Java EE/Tomcat configuration, I generally do one (or all) of 3 things:
Project/Clean
Right-click my server, and delete any artefacts (can't remember the exact command)
Source/Clean
I'm now playing around with the Google Eclipse Plugin for Appengine, which uses an inbuilt Jetty server.
Firstly, the plugin doesn't have any options to clean out generated class files before redeploying (well, not that I can see anyway). And secondly, the sever is not available as a configuration option.
Are there any quick fixes available to clean all artefacts/resources in my war/WEB-INF directory?
You can easily make it about one click and not unenviable. Just use ant and pattern matching. Open the ant view in Eclipse and add your file and it's just a click away.
Before 1.7 when app size was more limited, I used to copy almost everything out so I could upload it and serve from the blobstore (GWT permutations galore!). I was doing this alot!!!
see these for details http://ant.apache.org/manual/Types/fileset.html and http://ant.apache.org/manual/Tasks/delete.html
Here's my simple code example:
<target name="moveXprojectGae">
<delete includeemptydirs="true">
<fileset dir="XprojectGae" includes="**/*"/>
</delete>
<move todir="XprojectGae">
<fileset dir="war/XprojectGae">
<exclude name="**.rpc"/>
<exclude name="**nocache.js"/>
</fileset>
</move>
</target>

How to deploy Gwt RPC servlet on tomcat server?

I have apache-tomcat-7.0.16 and jdk1.6.0.25 on my window xp server. I install eclipse and copy the programer of stockwatcher from google site. I compile the program and run under eclipse development mode it is running fine. The eclipse create the war folder i copy this war folder under apache-tomcat-7.0.16/webapps.. then i check my tomcat server by enter http://localhost:8080: it is working and run example of servlet of tomcat as well. Then i enter the http://localhost:8080/war/stockwatcher.html. It give some java error. Then is move and copy again now give the error page not found.
Content of the war folder is
images
stockwatcher
web-inf
stockwatcher.css
stockwatcher.html
i think i copy the file on wrong location or i have to configure the tomcat
What is this java error you speak of?
Are you sure GWT libs are located inside WEB-INF/lib folder? Those are required for the GWT-RPC mechanism to operate.
Please visit the following sites for reference:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/3408c38464c57d4a?pli=1
GWT app - deploying on Tomcat or any other servlet container
do not use that war folder to deploy a gwt application to tomcat. it will not work. the procedure is:
1) gwt Compile the project first.
2) create a webbuilder.xml file and put the code under in it.
<project name="ExceptionReport" basedir="." default="default">
<target name="default" depends="buildwar,deploy"></target>
<target name="buildwar">
<war basedir="war" destfile="
ExceptionReport.war" webxml="war/WEB-INF/web.xml">
<exclude name="WEB-INF/**" />
<webinf dir="war/WEB-INF/">
<include name="**/*.jar" />
</webinf>
</war>
</target>
<target name="deploy">
<copy file="ExceptionReport.war" todir="." />
</target>
</project>
ExceptionReportis my project name.
3) export the src folder as JAR file and save it in war>webinf>lib.
4) right click on web builder file and choose ant build option. it will generate a war file in your project.
5) put that war file on tomcat. and restart yout tomcat.

Best way to deploy large *.war to tomcat

During development I frequently have to deploy a large war-file (~45 MB) to a remote test server, normally I copy the file with scp to the server.
The WEB-INF/lib folder makes up the largest part of the war file, which includes all the required libraries (spring, apache-cxf, hibernate,...).
Now I'm searching for an fast and easy a way to redeploy only my altered files.
And how can I determine which packages are really needed by the webapp, because spring and apache-cxf comes with a lot of libs, I'm sure I don't need all of them.
When you deploy a .war, the first thing Tomcat does is to unpack that file into its webapps directory, in a subdirectory with the same name as your .war.
During development, you obviously have access to your .class files, the .jar files, configuration files and whatever else eventually goes into your .war. You can easily establish a small subset of files affected by your changes. Figure that out, and then use a script or an ant task or whatever to copy just that small handful of files straight into the webapps/yourapp directory on the server.
To see your changes take effect, you'll need to re-start your application. If Tomcat is in development mode, one easy way to force a reload (and restart, of course) is to update WEB-INF/web.xml. So have your deployment process touch that file or otherwise update it in a way that will give it a new timestamp, scp that over too (preferrably as the last of the files you update) and you should have a quick and easy reload.
What I do is exclude WEB-INF/lib/*.jar files from the WAR and reassemble on the server side. In my case, this trims a 60MB WAR down to 250k which allows for really fast deployment.
The <exclude name="**/lib/*.jar"/> command is what excludes the jar's (see last code snippet for ANT build)
On the server side, it's quite easy to assemble a fully populated WAR from the trimmed WAR:
unzip/explode the trimmed WAR that was created by the ANT script below
copy the server repository jar files into the exploded WEB-INF/lib
zip is all up into a new (large) WAR.
deploy as usual.
For example:
unzip ../myapp.trimmed.war
mkdir WEB-INF/lib
cp ../war_lib_repository/* WEB-INF/lib
zip -r ../myapp.war .
Maybe not the most elegant solution, but it saves time on frequent deployment of large WAR's. I'd like to be able to do this with Maven so if anyone has suggestions, please let me know.
ANT build.xml:
<property file="build.properties"/>
<property name="war.name" value="myapp.trimmedwar"/>
<property name="deploy.path" value="deploy"/>
<property name="src.dir" value="src"/>
<property name="config.dir" value="config"/>
<property name="web.dir" value="WebContent"/>
<property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
<property name="name" value="${war.name}"/>
<path id="master-classpath">
<fileset dir="${web.dir}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<!-- other classes to include -->
<fileset dir="${birt.runtime}/ReportEngine/lib">
<include name="*.jar"/>
</fileset>
<pathelement path="${build.dir}"/>
</path>
<target name="build" description="Compile main source tree java files">
<mkdir dir="${build.dir}"/>
<javac destdir="${build.dir}" debug="true" deprecation="false" optimize="false" failonerror="true">
<src path="${src.dir}"/>
<classpath refid="master-classpath"/>
</javac>
</target>
<target name="createwar" depends="build" description="Create a trimmed WAR file (/lib/*.jar) excluded for size">
<!-- copy the hibernate config file -->
<copy todir="${web.dir}/WEB-INF/classes">
<!-- copy hibernate configs -->
<fileset dir="${src.dir}/" includes="**/*.cfg.xml" />
</copy>
<copy todir="${web.dir}/WEB-INF/classes">
<fileset dir="${src.dir}/" includes="**/*.properties" />
</copy>
<!-- copy hibernate classes -->
<copy todir="${web.dir}/WEB-INF/classes" >
<fileset dir="${src.dir}/" includes="**/*.hbm.xml" />
</copy>
<war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
<fileset dir="${web.dir}">
<include name="**/*.*"/>
<!-- exlude the jdbc connector because it's on the server's /lib/common -->
<exclude name="**/mysql-connector*.jar"/>
<!-- exclude these jars because they're already on the server (will be wrapped into the trimmed war at the server) -->
<exclude name="**/lib/*.jar"/>
</fileset>
</war>
<copy todir="${deploy.path}" preservelastmodified="true">
<fileset dir=".">
<include name="*.war"/>
</fileset>
</copy>
</target>
I use rsync to copy my .war from my local machine to production. It usually provides a big speed up, around 8-10 times.
Another option is to use git to store the .war files. When you git push a new .war, only the differences are transferred. Also a big speed up. Some people say that git is not designed to store big files, it gets slow and does not work very well. In fact yes, the repo will grow a lot, but in some cases it could be a good option.
Some numbers: My .war is about 50MB and when I deploy a new version, it only copies about ~4MB instead of uploading a complete new war. Both with git and rsync.
UPDATE: The problem I ran into it's the git repo cannot be cloned after it has several .war versions because it will take forever to create all the deltas and transmit them to the client.
I changed the strategy by uploading the .war files into dropbox. Dropbox also uses kind of rsync and only copies deltas. From the server I wget the .war and re-reploy the app. Hope this helps.
Improving on Rori Stumpf answer, here is a Gradle task for the 'thinning'
war {
archiveName "v1.war"
}
task createThinWar(type: Copy) {
dependsOn 'war'
def tmpFolder = "${buildDir}/tmp/thin"
def outputDir = "${buildDir}/libs"
// Extract the war (zip) contents
from zipTree("${outputDir}/v1.war")
into "${tmpFolder}/v1"
doLast {
// Extracting the war third party libraries to a separate dir
ant.move(file: "${tmpFolder}/v1/WEB-INF/lib", tofile: "${tmpFolder}/v1-libs")
// Zip the third party libraries dir
ant.zip(destfile: "${outputDir}/v1-libs.zip") {
fileset(dir: "${tmpFolder}/v1-libs")
}
// Finally zip the thinned war back
ant.zip(destfile: "${outputDir}/v1-thin.war") {
fileset(dir: "${tmpFolder}/v1")
}
}
}
This will generate v1-thin.war (weighting less then 1mb), and a libs zip.
deploy the thin war to the server (and reconstruct the libs there), and deploy the libs zip whenever you modified the versions/add libraries.
I don't think there's a faster way to redeploy only the changes to a WAR file.
If you deploy in exploded fashion you can see what file timestamps have changed and act accordingly, but you'll have to write code to do it.
I don't know if OSGi can be a help here. That would allow you to partition your problem into modules that are more independent and swap-able.
Just curious:
How long does it take now?
Do you use continuous integration to build and deploy?

Once saved in eclipse, copy project to a different directory

Using Eclipse, is there a way to automatically copy a file/project's directory to a different path once it's saved?
Effectively, when i save a file, it copies it from the workspace to the deploy directory
Workspace: "/code/my_app"
deploy to: "/application/plugins/my_app"
EDIT:
This is Mainly for Python and PHP projects
You can do that with Apache Ant pretty easily. There's even an Ant View in eclipse to run the script from. See the copy task.
Here's a sample ant build.xml file:
<project name="whatever" default="copy">
<target name="copy">
<copy todir="someDir">
<fileset dir="someOtherDir/" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</fileset>
</copy>
</target>
</project>
You can also add more targets for deploying your application.
Try “Ant Builder” :).
i have not tried this but this looks nearly what you want.