Tuesday, June 14, 2011

using maven to deploy to Tomcat 7

Ugh! I've been working on a simple webapp for a demo and using Maven for the build process. I was ready to deploy to a stand-alone instance of Tomcat 7 and I started to get a bunch of errors during the build when it came time to deploy to Tomcat. Using the -e switch for maven I started to see messages like:


[INFO] [tomcat:deploy {execution: default-cli}]
[INFO] Deploying war to http://localhost:8084/jasmineproject1
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Cannot invoke Tomcat manager

Embedded error: Server returned HTTP response code: 403 for URL: http://localhost:8084/manager/deploy?path=%2Fjasmineproject1&war=
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Cannot invoke Tomcat manager
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: Cannot invoke Tomcat manager
at org.codehaus.mojo.tomcat.AbstractCatalinaMojo.execute(AbstractCatalinaMojo.java:149)
at org.codehaus.mojo.tomcat.AbstractWarCatalinaMojo.execute(AbstractWarCatalinaMojo.java:70)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
... 17 more
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: http://localhost:8084/manager/deploy?path=%2Fjasmineproject1&war=
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
at org.codehaus.mojo.tomcat.TomcatManager.invoke(TomcatManager.java:604)
at org.codehaus.mojo.tomcat.TomcatManager.deployImpl(TomcatManager.java:662)
at org.codehaus.mojo.tomcat.TomcatManager.deploy(TomcatManager.java:295)
at org.codehaus.mojo.tomcat.AbstractDeployWarMojo.deployWar(AbstractDeployWarMojo.java:85)
at org.codehaus.mojo.tomcat.AbstractDeployMojo.invokeManager(AbstractDeployMojo.java:85)
at org.codehaus.mojo.tomcat.AbstractCatalinaMojo.execute(AbstractCatalinaMojo.java:141)


Apparently, with Tomcat 7, the manager URL has changed, so deployments from an IDE, a build tool or the command line can't be done the old way.

I took look at the Tomcat documentation for the manager application, and the docs say:

All commands that the Manager application knows how to process are specified in a single request URI like this:

http://{host}:{port}/manager/text/{command}?{parameters}

where {host} and {port} represent the hostname and port number on which Tomcat is running, {command} represents the Manager command you wish to execute, and {parameters} represents the query parameters that are specific to that command.



But when I use the path /manager/text for anything I get a server response of:


FAIL - Unknown command /text


Does anyone know what the correct URL to deploy a webapp to Tomcat 7 is now? For now, I can get away with using NetBeans deploying directly to Tomcat and not using maven to build and deploy, but in the long run that is not a solution...

Update:
Found an obscure link, which I cannot remember off the top of my head, that documented that the URL for using the manager in Tomcat 7 should be /manager/html and not /manager/text as the Tomcat documentation states. Hmm... makes you wonder sometimes if someone actually verifies documentation before publishing it to the world...

Wednesday, June 8, 2011

Jasmine Javascript debugging? Maybe not quite there...

Whew! Sorry about going dark for a while. Am no longer a consulting Tech Architect at Boeing Commercial Aircraft and just started in a SW Architect/Engineer position at Fabric WorldWide...

Inherited the responsibility for writing new and maintaining existing Javascript plugins used in BA/BI of websites. Lot's of interesting asynchronous code, not necessarily strictly adhering to the "X" in AJAX. Since the code loads and executes asynchronously, it is difficult to unit test during the build process. So I have been looking into Javascript testing frameworks that can 1) run headless, i.e. not require a browser; 2) not require jQuery or other framework that supplies DOM access; 3) can test code asynchronously; 4) is compatible with Maven; 5) provides Mock capabilities.

Some candidates were Screw-Unit, jsUnit, QUnit, JSpec, YUI Test, DOH, and Jasmine. For one reason or another they started to drop off the list and that left me with Jasmine. It took a little while to get everything installed correctly into my dev environment and getting Maven configured corectly, but once that was done, it seemed like it would be smooth sailing to test some new code I was writing.

Interestingly, when I had Firebug activated on FF 4.x, I would get a SyntaxError when trying to eval() a regular expression string. I figured I could catch that error in a Jasmine test before it even got to a browser session. Unfortunately, no - Jasmine's Javascript engine does not generate an error when executing eval() on the same string that I sent to the browser. I had been counting on it trapping the error so I could return something informative to the caller, but it looks like I will have to try something else...

So much for trapping and throwing errors in Javascript during unit testing...
SIGH!