How to set tomcat work at debug mode? - java

I deploy a application to tomcat with context xml. I want the tomcat work at debug mode, I means if I change something inside a function, like change
String a="123";
to
String a="456";
tomcat should get the change without reload the application.
The web01.xml under %CATALINA_HOME%/conf/Catalina/localhost
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="d:/document/workspace3.6/web01/WebContent" path="/web01" reloadable="false" debug="1" ></Context>
but now tomcat didn't worked as I expected, if I replace the old class file with new version, I must restart tomcat to get the change.
Why tomcat didn't reload the class,How should I do to let it work as debug mode?
I am not use Eclipse now. and I don't want to set reloadable="true", this will reload the entire application if class changed.
I used tomcat5.5.23

You're actually confusing the notions of "debugging" and hot deploy. You can configure Tomcat for debug mode, and then remotely debug your application running inside tomcat such that when you add a break point in your code, the debugger will jump to that breakpoint and halt execution.
What you actually need there is having the possibility to hotdeploy an application. With tomcat, if you modify the .java files and then copy them to the working directory of tomcat, you'll get exactly what you want, namely the ability to change something in a class and have the running tomcat-deployed application take it into account without redeploying the whole application. You can automatize this by configuring your tomcat application context (either in the tomcat server.xml file or in a project specific context.xml file) for your application to have as working directory the directory where your project code gets compiled.
here's an actual example:
Let's say you have a maven project in the directory c:\myProject. You'd have source files in the c:\myProject\src, and then when compiling it you'd get the war file and an exploded directory of the war file content in the c:\myProject\target\myProject.war and respectively c:\myProject\target\myProject. Now, if you configure your tomcat such that for the myProject tomcat context, youd have the working directory configured as c:\myProject\target\myProject, then each time you modify a .java file, the .class corresponding file will be updated in the target (and now also working) dir, and tomcat will take it into account.
I've actually used such a setup to develop with tomcat, but it's not the best. First off tomcat will hotdeploy only certain modifications, such as when you modify something in the body of an existing method. Other modifications will not be taken into account, such as adding a new method - for this you have to do a full redeploy to have it taken into account.
A far better solution is to use maven with the maven jetty plugin. This thing really works as you want: any modification you do to a class of jsp file will me immediately taken into account, and visible in the running app inside jetty.

Ok, here's an actual example:
I have the cnas-war maven project. Once I build it with Maven, I get the following directory:
c:/_andrei/work/cnas/cnas-war/target\cnas-war-0.0.1-SNAPSHOT
In here I have all the stuff that normally would get packaged in the .war file, like .class files, .jsp files, .jar files etc. Effectively it's the .war file exploded.
I also have a Tomcat 5.5 specifically tailored for the deployment of this war, cleverly placed in the tomcat_cnas folder. In the Tomcat config file (conf\server.xml) I have the following:
<?xml version="1.0" encoding="utf-8"?>
<!-- Example Server Configuration File -->
<!-- Note that component elements are nested corresponding to their
parent-child relationships with each other -->
<!-- A "Server" is a singleton element that represents the entire JVM,
which may contain one or more "Service" instances. The Server
listens for a shutdown command on the indicated port.
Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" or "Loggers" at this level.
-->
<Server port="8125" shutdown="SHUTDOWN">
<!-- Comment these entries out to disable JMX MBeans support used for the
administration web application
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/> -->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<!-- Global JNDI resources -->
<GlobalNamingResources>
<!-- Test entry for demonstration purposes -->
<Environment name="simpleValue" type="java.lang.Integer"
value="30" />
<Resource auth="Container"
configurationDirectory="c:/cnas-content"
factory="com.genia.toolbox.web.jndi_config.StringContainerFactory"
name="string/activitymanagerConfigurationContainer"
type="com.genia.toolbox.web.jndi_config.StringContainer" />
<Resource name="string/activitymanagerConfigurationContainer"
auth="Container"
type="com.genia.toolbox.web.jndi_config.StringContainer"
factory="com.genia.toolbox.web.jndi_config.StringContainerFactory"
configurationDirectory="c:/cnas-content" />
</GlobalNamingResources>
<!-- Define the Tomcat Stand-Alone Service -->
<Service name="Catalina">
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector acceptCount="100" connectionTimeout="20000"
disableUploadTimeout="true" enableLookups="false"
maxHttpHeaderSize="8192" maxSpareThreads="75" maxThreads="150"
minSpareThreads="25" port="8081" redirectPort="8443" />
<!-- Define the top level container in our container hierarchy -->
<Engine defaultHost="localhost" name="Catalina">
<!-- for activitymanager -->
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="true" xmlValidation="false"
xmlNamespaceAware="false">
<Context path="/cnas"
docBase="c:/_andrei/work/cnas/cnas-war/target/cnas-war-0.0.1-SNAPSHOT/"
workDir="c:/_andrei/work/cnas/cnas-war/target/work-cnas/">
<ResourceLink name="string/configurationContainer"
global="string/activitymanagerConfigurationContainer"
type="com.genia.toolbox.web.jndi_config.StringContainer" />
<Resource name="bean/cnasConfig" auth="Container"
type="com.genia.toolbox.projects.cnas.war.config.CnasConfig"
factory="org.apache.naming.factory.BeanFactory"
classpath="false" fileSystem="true"
applicationFileLocation="c:/cnas-content/application.properties" />
<Resource name="bean/cnasApplicationData"
auth="Container"
type="com.genia.toolbox.projects.cnas.war.config.CnasConfig"
factory="org.apache.naming.factory.BeanFactory"
classpath="false" fileSystem="true"
applicationFileLocation="c:/cnas-content/cnas_application_data.xml" />
</Context>
<!--Context docBase="C:/travail/workspace/cnas/cnas-ws-proxy/target/webapp" path="/proxy">
<Resource name="bean/params"
auth="Container"
type="fr.genia.cnas.config.Parameters"
factory="org.apache.naming.factory.BeanFactory"
log4jFile=""
serviceUrl=""
debugMode="true" >
</Resource>
</Context-->
</Host>
</Engine>
</Service>
</Server>
As you can see, in the "context" tag I have a docBase property pointing to the snapshot directory (the one where the war is exploded after maven builds it). Now, with this setup, and having this project imported into Eclipse, if I do a maven build, and then start this Tomcat, the war will be deployed and running. At this point, if I modify the content of a method in a .java file inside Eclipse (and save), then that code will be automatically taken into account by Tomcat and the application will behave differently, without any extra re-deployment. Hope this helps

How to configure Tomcat 5.5 for debug mode?

To do what you are trying to do, You would need some thing like java rebel or some thing similar I know there are some open source alternatives to do the same.

Related

Maven tomcat with external server.xml file for multi profile project

I am working on multi profile project and its maven pom file hierarchy parent pom file contailn the tomcat7 plugin.
Parent pom.xml
|--child1 pom.xml
|--child2 pom.xml
|--child3 pom.xml
|--child4 pom.xml
|--child5 pom.xml
Profiles
Parent pom.xml
profiles
profile1 modules
|--child1
|--child2
profile2 modules
|--child1
|--child3
|--child4
I am willing to have following external server.xml file
<?xml version='1.0' encoding='utf-8'?>
<Server port="8080" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Listener className="it.xxx.tomcat.listener.TBXServerLifecycleListener"/>
</Host>
</Engine>
</Service>
</Server>
And i have configured server.xml file location in tomcat plugin itself
<serverXml>${user.dir}\conf\server.xml</serverXml>
Without this external config file tomcat is starting fine but after adding this tomcat plugin doesn't idetify war file in the selected profile,
Acccording to the following answer I must configure webapp paths in this file.
https://stackoverflow.com/a/26004617/1709600
But in my priject i have around 50 profiles and each profile webapps are diffetent. I cannot configure every webapp in this single server.xml file.
Then my question is ,
Is there way to and webapps path in tomcat plugin itself ???
without adding following xml tag to server.xml file server.xml
<Context docBase="../../webapp" path="/webapp" reloadable="true" />
I have already play with following configurations but any of this didn't work for me ... :(
<defaultContextFile>${user.dir}\conf\context.xml</defaultContextFile>
<warSourceDirectory>${project.build.directory}/${project.build.finalName}/</warSourceDirectory>
<warDirectory>${project.build.directory}/${project.build.finalName}/</warDirectory>
<warFile>${project.build.directory}/${project.artifactId}.war</warFile>
My Maven command :
tomcat7:run-war-only -P profileX

Jenkins war deployment to Tomcat 7

I'm using Jenkins for war deployment to my remote server which uses Tomcat 7.
I need my application to be directly installed at dedicated port like this:
http://localhost:8083
instead of usual:
http://localhost:8080/myCoolApp
To achieve this I deploy my war archive as ROOT directly to 'webapp' Tomcat's directory.
Everything works fine, archive is sent and deployed but I get an error from Jenkins:
Just to remind - archive is deployed successfully!
But as a perfectionist I just can't stand a result like this.
Here is my configuration for Jenkins deployment:
Here is Tomcat configuration for my application as a separate service:
<Service name="Jangel">
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" />
<Engine name="Jangel" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
<Host name="localhost" appBase="Jangel" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
So the question is - how should I configure correctly Tomcat&Jenkins?
Or how may I avoid/silence this Jenkins error?
Try this by replacing the context path in your jenkins deployment by / (slash) instead of writing ROOT.

not able to deploy, context file broken

i used tomcat 7 and netbeans 7.4
when i start my web application i get
Cannot deploy the module. The context.xml file seems to be broken. Check whether it is well-formed and valid.
The module has not been deployed.
it's my context.xml file
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/shareDS" auth="Container" type="javax.sql.DataSource"
maxActive="50" maxIdle="10" maxWait="100000"
username="${db.user}" password="${db.password}" driverClassName="com.mysql.jdbc.Driver"
url="${db.url}"
timeBetweenEvictionRunsMillis="1800000" autoReconnect="true"
removeAbandoned="true" removeAbandonedTimeout="300" logAbandoned="true"/>
</Context>
when i try to validate my context file, i get
Cannot find the declaration of element 'Context'. [19]
any idea?
Figured it out. The Netbeans deployment process wants you to add 1 simple parameter to the Context tag, namely: path. It needs to know what path the application will be on.
For example, this was my (opening) Context tag:
<Context antiJARLocking="true" path="/sas/">
My application is deployed at the /sas/ context root.
And now, Netbeans deploys my application without any further errors.
FYI: the antiJARLocking is something I put in to avoid locking of JAR's. It's not mandatory.
For more information on the antiJARLocking, refer to the documentation over at: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html

Deployment strategy for Jetty and Scala with SBT?

I'd like to have Jetty running on a production server and when I have a new code package to deploy I'd like to be able to do an "sbt package" to package up my code into a war file, then copy it over to the production machine's webapp folder.
Is that reasonable? If so, what is the best way to start Jetty as a daemon? Will it see the new file and automatically reload my app or do I need to restart it somehow?
The main problem with what you are suggesting is that the configuration required to have the server listen or monitor the webapps folder is that there will be a production hit.
While this type of configuration is great for development, it isn't recommended for production applications.
With that said, what you're looking for is a ContextDeployer, which can be configured in jetty.xml. See the Jetty documentation for your specific version of Jetty for the exact details:
<!-- =========================================================== -->
<!-- Configure the context deployer -->
<!-- A context deployer will deploy contexts described in -->
<!-- configuration files discovered in a directory. -->
<!-- The configuration directory can be scanned for hot -->
<!-- deployments at the configured scanInterval. -->
<!-- -->
<!-- This deployer is configured to deploy contexts configured -->
<!-- in the $JETTY_HOME/contexts directory -->
<!-- -->
<!-- =========================================================== -->
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">5</Set>
</New>
</Arg>
</Call>
The "scanInterval" is what tells the server to monitor the contexts folder. Every 5 seconds, it checks to see if the files changed.
Finally, to start Jetty as a daemon, just use the scripts they provide you in the /bin folder:
./jetty.sh start
To stop Jetty, run:
./jetty.sh stop
And to restart Jetty, run:
./jetty.sh restart
Again, see The Jetty Documentation or The Webtide Website for the exact documentation for whatever version of Jetty you're running. Different versions can differ drastically in terms of how the server is configured.

Issue with JNDI resource with Tomcat 6 on Linux with WAR file

I'm fairly new to Tomcat and Java web development and am banging my head against a wall with an issue im experiencing.
I have a web application that works fine on my local box (windows xp), I have Tomcat 6 installed with the WAR file deployed to the webapps folder and within the c:/apache-tomcat-6.0.18/conf/Catalina/localhost/ directory i have the "myApp.xml".
The myApp.xml contains the following:
<Context path="/myApp" docBase="/myApp.war" debug="1" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" scope="Shareable" type="javax.sql.DataSource" auth="Container" username="test" password="test" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
Then within my web app i have the following info within my applicationContext file
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/sql-connection</value>
</property>
</bean>
Now i've gone from it all working fine on my local box to deploying it on a Linux box, however when I deploy it on there, with exactly the same setup just tomcat is running from "opt/apache-tomcat-6.0.18". Every time I try to start Tomcat on the box it will unpack the WAR file but wont start it, and gives me the following error whenever i try to start it through the manager:
Error creating bean with name 'myDatasource' defined in file [/opt/apache-tomcat-6.0.18/webapps/myApp/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
Ive tried looking all over the internet for an answer but nothing seems to have the exact same issue, and the names seem to match between the tomcat config file and the web app.
First of all, Tomcat doesn't understand myApp.xml (unless you explicitly points it to it, which I don't know how). Tomcat works based on context, which can be configured for your web application. Tomcat allows only deployment of Web Aplication Archive (WAR) file.
To create a context for your application, create a context.xml (all small caps, case-sensitive) file inside your Web application META-INF folder.
Your reference guide to configuring context can be found on Tomcat 6 Config/Context. You will see that attribute debug is deprecated.
The JNDI Resources HOW-TO for Tomcat 6 is also available.
Once you have created your context.xml inside your META-INF folder, paste the following code (taken from your example) below:
<Context path="/myApp" docBase="/myApp.war" reloadable="true" cookies="true">
<Resource name="jdbc/sql-connection" type="javax.sql.DataSource" auth="Container" username="test" password="test" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://xxxx:xxxx;appName=myApp" removeAbandoned="true" logAbandoned="true" />
</Context>
(By default, Tomcat uses PoolableDataSource for Connection Pooling).
Once you're done, config your <resource-env-ref> in your WEB-INF/web.xml. That will allow you to create Shareable scope. Please refer to the link provided on Tomcat 6 JNDI, HOW-TO.
I hope this helps you.

Categories

Resources