dotCMS - Open Source Content Management System, Ondemand CMS, and Professional Support

Document Search

Article Information

Since Version: 1.6.5
Tags: war installation svn
Updated: 2/3/2010 1:52:11 PM
By: Dean Gonzalez
Doc id: 577231
Print Page: Export to PDF

Installing from SVN to War

Special thanks to Will Caine for contributing the original documentation that was later reviewed and edited by the dotCMS team.

It turns out that the configuration of Tomcat you get from SVN-stable (https://svn.dotcms.org/branches/stable) provided by dotCMS was valid. It was the ant build.xml that is a problem. It bundles in way too many jars compared to what is needed to make this guy work. Many conflicting jars I found with my Tomcat 6.0.16.

Table of Contents

Jar Locations What to and Not to Include
/conf/Catalina/localhost/ROOT.xml changes
In the context.xml file
Make changes to the catalina.properties file to bring all your classes in
Make changes to the catalina.sh file to the security rules to be able to login to the admin screen
Define GLOBAL_VARIABLES_PATH in dotmarketing-config.properties
Plugins Deploy not working / Plugins not installing right
Issues / Places to Check
Run on MySQL without the lower_case_table_names=1
Extras
Make this work on a 64MB heap space
Drawbacks/Issues

Jars that should not be included anywhere [Top]

To name a few that should not be bundled anywhere from the SVN checked out code since Tomcat has these already

  • jsp-api.jar - its an older version of the JSP spec that causes compile errors
  • servlet-api.jar

Jars that should be moved to the common/lib folder [Top]

 

  • naming-* jars - if not in the shared lib folder caused the datasource to not be picked up (something to do with the class loader hierarchy I think)
  • even the dotCMS_1.7a.jar file
  • ALMOST ALL THE REST OF THE JARS - again if they are all not at the right level in the class loader hierarchy you will get class not founds and all sorts of wierd errors.

Jars to keep in the WEB-INF/lib of the war

The only jars I kept in the WEB-INF/lib folder of the war built were the ones that the checked out version of dotCMS had and they are

batik-awt-util.jar
batik-dom.jar
batik-svggen.jar
batik-util.jar
batik-xml.jar
cewolf.jar

Copy from the SVN version to the "clean" Tomcat build

[svn checkout]/conf/jaas.config --> [clean tomcat]/conf/jaas.config

[svn checkout]/common/* --> [clean tomcat]/common/* [had to make this directory]

/conf/Catalina/localhost/ROOT.xml changes [Top]

 

  1. Create a META-INF folder inside ./dotCMS folder from the checked out code
  2. copy the ROOT.xml file to the new META-INF folder
  3. rename the ROOT.xml file to context.xml

What this will do is when the war is created by your ant script the META-INF folder will be included and when you go to deploy the war, Tomcat will install the context.xml file for you into the conf folder in the correct place.

In the context.xml file: [Top]

 

In the first line where you see

<Context path="" docBase="../dotCMS" debug="0" reloadable="false" crossContext="true">

change to

<Context path="" debug="0" reloadable="false" crossContext="true">

The docBase is not needed anymore because we have a war file now.  Tomcat will figure out the base path for us.

Make changes to the catalina.properties file to bring all your classes in [Top]

 

common.loader=${esc.d}{catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.home}/server/lib/*.jar,${catalina.home} /common/ext-ejb,${catalina.home}/common/lib/ext/*.jar,${catalina.home}/common/lib/*.jar,${catalina.home}/common /endorsed/*.jar,${catalina.home}/build/instrumented,${catalina.home}/build/classes

This will put all of the jars you copied into the common/lib/ location onto your classpath.

Make changes to the catalina.sh file to the security rules to be able to login to the admin screen [Top]

 

/bin/catalina.sh

CATALINA_OPTS="-Xms64m -Xmx64m -Djava.security.auth.login.config=$CATALINA_HOME/conf/jaas.config " echo "Using CATALINA_OPTS: $CATALINA_OPTS"

I also defined the heap size to limit myself to see how small I could make the imprint. You should use at least 512 unless you wanna get OutOfMemoryErrors once and a while

Define GLOBAL_VARIABLES_PATH in dotmarketing-config.properties [Top]

 

Define GLOBAL_VARIABLES_PATH in dotmarketing-config.properties because in my case, my tomcat is setup to handle mutiple roots so its inside [tomcat root]/domains/[some.com]/context and if not defined you will see in the logs...

java.io.FileNotFoundException: [some server root/>stuff]/tomcat/domains/[some.com]/context/../common/ext-ejb/...

...This is the default path that is only correct if you are using the setup that comes with the tomcat configuration when checked out of SVN. Instead you want
[some server root stuff]/tomcat/common/ext-ejb/

So define that property to your common/ext-ejb folder in the properties file and you will stop seeing FileNotFoundExceptions.

GLOBAL_VARIABLES_PATH=/[some server root stuff]/tomcat/common/ext-ejb

Plugins Deploy not working / Plugins not installing right [Top]

On server start, InitServlet makes a call to the PluginLoader
new PluginLoader().loadPlugins(config.getServletContext().getRealPath("."),classPath);
This tries to load all the extension jars at ../common/lib/ext This is wrong when running your app as a WAR because it creates a folder called ROOT
/Development/servers/apache-tomcat-6.0.16/webapps/ROOT/../common/lib/ext
which tries to target
/Development/servers/apache-tomcat-6.0.16/webapps/common/lib/ext

which is not a valid directory because in my case, my tomcat is setup to handle mutiple roots so its inside [tomcat root]/domains/[some.com]/context.  So it does not find that directory and it fails over to

/Development/servers/apache-tomcat-6.0.16/webapps/ROOT/WEB-INF/lib

which is valid however is not where i put the jar extensions.


Because I keep my plugins in common/lib/ext and they are never found, the Plugin Deploy class never gets run and my plugins are never setup correctly 

Workaround

Put the extension inside the WEB-INF/lib

Or better yet:

The logic here should be more robust to check the WEB-INF/lib using the getServletContext().getRealPath(".") as well as make use of the property GLOBAL_VARIABLES_PATH in the /common/ext-ebj/dotmarketing-config.properties file so that if can correctly discover the true ROOT and not have to use relative navigation to find the common/lib/ext. The relative navigation can be a fall back if GLOBAL_VARIABLES_PATH is not set.

I found this function in ContentletAjax.java that does the trick which I then put into InitServlet.java. Weirdly enough this function is private and used in multiple classes.

  • ContentletAjax.java
  • LanguageFactoryImpl.java
  • EditUserFilterAction.java
  • Task00005MoveLanguageFiles.java

So I took this function, stuck it in InitServlet.java and got it working

public class InitServlet extends HttpServlet {
....

private String getGlobalVariablesPath() {
String globalVarsPath = Config.getStringProperty("GLOBAL_VARIABLES_PATH");
if (!UtilMethods.isSet(globalVarsPath)) {
globalVarsPath = Config.CONTEXT.getRealPath(File.separator + ".." + File.separator + "common"
+ File.separator + "ext-ejb" + File.separator + "content" + File.separator);
}
if (!globalVarsPath.endsWith(File.separator))
globalVarsPath = globalVarsPath + File.separator;
return globalVarsPath;
}

public void init(ServletConfig config) throws ServletException {
.....
//String classPath = config.getServletContext().getRealPath("../common/lib/ext");
String classPath = getGlobalVariablesPath() + "../lib/ext";
File extDir = new File(classPath);
if(!extDir.exists()){
classPath = config.getServletContext().getRealPath("WEB-INF/lib");
}
.....
}
.....
}

Issues / Places to Check [Top]

Name java:comp is not bound in this Context
Symptoms: dotCMS will not start because cannot get datasource

Caused by: com.dotmarketing.exception.DotRuntimeException: com.dotmarketing.exception.DotRuntimeException: javax.naming.NameNotFoundException: Name java:comp is not bound in this Context
	at com.dotmarketing.exception.DotRuntimeException.fillInStackTrace(DotRuntimeException.java:33)
	at java.lang.Throwable.(Throwable.java:181)
	at java.lang.Exception.(Exception.java:29)
	at java.lang.RuntimeException.(RuntimeException.java:32)
	at com.dotmarketing.exception.DotRuntimeException.(DotRuntimeException.java:15)
	at com.dotmarketing.db.DbConnectionFactory.getConnection(DbConnectionFactory.java:92)
	at com.dotmarketing.db.HibernateUtil.getSession(HibernateUtil.java:498)
Possible Solution:

Make sure your context.xml file is setup correctly and it is giving you the correct access of the datasource to your app.

Make sure the naming-* files are not in the WEB-INF/lib but in the common lib folder. Has to do with classloader hierarchy

Helpful URL(s):

http://forums.sun.com/thread.jspa?threadID=5117657

java.lang.SecurityException: Unable to locate a login configuration
Symptoms: startersite will not let me login
-Make sure the jaas.config is defined via -Djava.security.auth.login.config=$CATALINA_HOME/conf/jaas.config" on startup of Tomcat Has to do with classloader hierarchy. OR I saw a way to during runtime define it but I havn't tried it.

Helpful URL(s):
https://www.liferay.com/web/guest/community/forums...
http://forums.sun.com/thread.jspa?threadID=569847

ServletException: Wrapper cannot find servlet class org.apache.jsp.index_jsp or a class it depends on

Symptoms: when hit url will get compile/runtime error
-make sure your JSPs compiled and were put into the dotcms_1.7a.jar(mine was about 8MB with compiled jsps, 4MB without)

NoSuchMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext

Symptoms: when hit url will get compile/runtime error Make sure there are no conflicting jars inside your war like servlet-api and jsp-api that define a different spec. in this case the class was build on JSP 2.1 but Tomcat runs 2.0 Helpful URL(s):

http://java.sun.com/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspApplicationContext.html
http://www.nabble.com/Problems-with-precompiled-JSP-on-Tomcat-5,5-td16129348.html
http://www.mail-archive.com/users@myfaces.apache.org/msg43119.html

Run on MySQL without the lower_case_table_names=1 [Top]

In the documentation is says that lower_case_table_names number equal 1

http://www.dotcms.org/documentation/SoftwareRequirements

In the code the same table is referenced in more than one case so I wrote my own mySQL driver that wrappered the standard mysql code: ConnectionImpl, StatementImpl and PrepareStatementImpl.  I then intercepted, anywhere a create statment, execute query, or prepare statment was called on these objects rewrote the SQL to make for example users_group be rewritten to Users_Groups and then passed the SQL onto the com.mysql driver code.

Sample driver code for my implementation of ConnectionImpl
private PreparedStatement wrapPrepareStatement(
PreparedStatement prepareStatement) throws SQLException {
return new DotPreparedStatement(conn, getCatalog(),
(com.mysql.jdbc.PreparedStatement) prepareStatement);
}

public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
//rewrite the sql to fix table naming issues
sql = DotDriver.translateString(sql);
return wrapPrepareStatement(conn.prepareStatement(sql, resultSetType,
resultSetConcurrency, resultSetHoldability));
}
told the context xml to use my new driver that I named DotDriver
<Resource name="jdbc/dotCMSPool" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.DotDriver"
url="jdbc:mysql://localhost/wacaine5_cainedotcms?characterEncoding=UTF-8"
username="wacaine5_dotcms" password="dotcms3146" maxActive="60" maxIdle="10" maxWait="60000"
removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
validationQuery="SELECT 1" testOnBorrow="true"/>
to get at runtime when sql is executed
DotDriver translated sql: insert into users_groups values (?,?)  to  insert into Users_Groups values (?,?)  using rule:users_groups-->Users_Groups

BUT when I went to the server it uses org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper which somehow changes the implementation back to the normal mysql somehow. If I could figure this out it would have saved me this next step.

To get around the server ignoring my driver I had to actually put the code in DotConnector and DotHibernate classes to intercept and rewrite SQL until I can figure out how PoolingDataSource works where I can make it stop ignoring my driver.

These were all the tables I had to make rules for.  To shorten the list, i removed after the first entry the extra stuff I added to control rule behavior.

users_groups.rule=users_groups->Users_Groups
users_groups.caseSensitive=true
users_groups.type=findReplace
users_groups.active=true
users_groups.object=any

groups_roles.rule=groups_roles->Groups_Roles
portlet.rule=portlet->Portlet
address.rule=address->Address
group.rule=group_->Group_
layout.rule=layout->Layout
user.rule=user_->User_
role.rule=role_->Role_
company.rule=company->Company
users_roles.rule=users_roles->Users_Roles
counter.rule=counter->Counter
image.rule=image->Image
portletpreferences.rule=portletpreferences->PortletPreferences

Extras [Top]

Make this work on a 64MB heap space [Top]

To make this work on a 64MB heap space in Tomcat 6.0.16 I had to truncate the dictionary files. They ate up a lot of heap space since they are held in memory and if I left them in there I would get an OutOfMemoryException

Drawbacks/Issues [Top]

I was unsuccessful at getting dotCMS to deploy anywhere but the ROOT context path. I was able to change it, but there seem to be some hard coded redirections based on the root that I could not get around without modifying code (the admin page root.com/c in particular)

There are a lot of jars now on the common classpath. Observe for collisions or incompatibilities with other apps you try to deploy



Post a Comment


Add Comments

   

 
Post

Powered by Olark