Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 472178

Summary: www-servers/tomcat: permit switching tomcat-juli.jar and/or enable tomcat-extras tomcat-juli.jar replacement
Product: Gentoo Linux Reporter: Tiziano Müller (RETIRED) <dev-zero>
Component: Current packagesAssignee: Java team <java>
Status: CONFIRMED ---    
Severity: normal CC: jstein
Priority: Normal Keywords: PATCH
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---

Description Tiziano Müller (RETIRED) gentoo-dev 2013-06-03 15:42:28 UTC
My problem with the current tomcat setup is that there is no proper way to replace the default tomcat-juli.jar (which is a renamed commons-logging hardcoded to use JUL) by either the extras version provided in the tomcat tarball (a renamed commons-logging with full backend selection) or yet another solution like https://code.google.com/p/tomcat-slf4j/ to log to something different than files/stdout/stderr.

One solution could be to install the default tomcat-juli.jar somewhere else (not in $CATALINA_HOME/bin) and then have a eselect-manageable symlink which defaults to the default tomcat-juli.jar.
Given that, one could then add one of the following options to enable different logging backends for tomcat:
* https://code.google.com/p/tomcat-slf4j/
* renamed version of commons-logging
* renamed version of jcl-to-slf4j (https://github.com/grgrzybek/tomcat-slf4j-logback/)

It would be really nice if this could be configured per-instance since it wouldn't be necessary to add yet another eselect modul for something many people won't even need. But this is beyond my java-knowledge...

If you can agree on a solution I could also implement it.

(the problem with jul-to-slf4j as described in http://hwellmann.blogspot.ch/2012/11/logging-with-slf4j-and-logback-in.html is it's rather heavy negative performance impact)
Comment 1 Tiziano Müller (RETIRED) gentoo-dev 2013-06-05 11:54:22 UTC
After a lot of discussion with Caster we came up with the following ideas:

1) splitting the tomcat-juli.jar into two: one which contains the tomcat-specific classes (ClassLoaderManager) named "tomcat-juli.jar" and one which contains solely the renamed, hardcoded commons-logging classes "tomcat-juli-jcl.jar". This could be upstream'able.
2) adding a "juli" USE flag to commons-logging which triggers the build of a second jar where the package gets renamed from org.apache.commons to org.apache.juli
3) Add some switch to the tomcat conf.d/init.d scripts to trigger the use of an alternative jar to the above mentioned "tomcat-juli-jcl.jar" plus adding more jars as required by the logging framework ("tomcat-juli-adapter.jar" for example) such that the user can simply install commons-logging[juli] and then set LOGGING_FRAMEWORK="commons-logging" (instead of the default "native") to use the full (renamed) commons-logging which would then in turn provide log4j logging.
4) the same as in 2) can be done to log4j, jcl-to-slf4j, slf4j, logback to permit the usage of those logging libraries within tomcat without interfering with jars possibly provided/required by webapps (as implemented in https://github.com/grgrzybek/tomcat-slf4j-logback/)

Other ideas?
Comment 2 Tiziano Müller (RETIRED) gentoo-dev 2013-10-02 08:32:27 UTC
An easier solution is to just bundle commons-logging if the user requests extra-logging:

--- tomcat-7.0.42.ebuild	2013-07-08 18:57:56.000000000 +0200
+++ tomcat-7.0.42-r1.ebuild	2013-10-02 10:28:08.000000000 +0200
@@ -9,15 +9,17 @@
 inherit eutils java-pkg-2 java-ant-2 prefix user
 
 MY_P="apache-${P}-src"
+COMMONS_LOGGING_P="commons-logging-1.1.1-src"
 
 DESCRIPTION="Tomcat Servlet-3.0/JSP-2.2 Container"
 HOMEPAGE="http://tomcat.apache.org/"
-SRC_URI="mirror://apache/${PN}/tomcat-7/v${PV}/src/${MY_P}.tar.gz"
+SRC_URI="mirror://apache/${PN}/tomcat-7/v${PV}/src/${MY_P}.tar.gz
+	extra-logging? ( mirror://apache/commons/logging/source/${COMMONS_LOGGING_P}.tar.gz )"
 
 LICENSE="Apache-2.0"
 SLOT="7"
 KEYWORDS="~amd64 ~ppc ~ppc64 ~x86 ~x86-fbsd ~x86-freebsd ~amd64-linux ~x86-linux ~x86-solaris"
-IUSE="extra-webapps"
+IUSE="extra-logging extra-webapps log4j"
 
 RESTRICT="test" # can we run them on a production system?
 
@@ -27,6 +29,7 @@
 COMMON_DEP="
 	dev-java/eclipse-ecj:${ECJ_SLOT}
 	~dev-java/tomcat-servlet-api-${PV}
+	extra-logging? ( log4j? ( dev-java/log4j:0 ) )
 	extra-webapps? ( dev-java/jakarta-jstl:0 )"
 RDEPEND="${COMMON_DEP}
 	!<dev-java/tomcat-native-1.1.24
@@ -49,7 +52,23 @@
 
 java_prepare() {
 	find -name '*.jar' -exec rm -v {} + || die
-	epatch "${FILESDIR}/${P}-build.xml.patch"
+	epatch \
+		"${FILESDIR}/${P}-build.xml.patch" \
+		"${FILESDIR}/${P}-build.xml-extra-logging.patch"
+
+	if use extra-logging ; then
+		mkdir -p output/extras/logging/ || die
+		ln -s ../../../../${COMMONS_LOGGING_P} output/extras/logging/ || die
+		# yes, we are duplicating what's in the commons-logging ebuild, unfortunately
+		cd "${WORKDIR}/${COMMONS_LOGGING_P}"
+		epatch \
+			"${FILESDIR}/${COMMONS_LOGGING_P/-src}-gentoo.patch" \
+			"${FILESDIR}/${COMMONS_LOGGING_P/-src}-servletapi.patch"
+		java-ant_ignore-system-classes
+		echo "jdk.1.4.present=true" > build.properties
+		use log4j && echo "log4j12.jar=$(java-pkg_getjars log4j)" >> build.properties
+		cd -
+	fi
 
 	# For use of catalina.sh in netbeans
 	sed -i -e "/^# ----- Execute The Requested Command/ a\
@@ -66,6 +85,7 @@
 EANT_EXTRA_ARGS="-Dversion=${PV}-gentoo -Dversion.number=${PV} -Dcompile.debug=false"
 
 src_compile() {
+	use extra-logging && EANT_BUILD_TARGET+=" extras-commons-logging"
 	EANT_GENTOO_CLASSPATH_EXTRA+=":$(java-pkg_getjar --build-only ant-core ant.jar)"
 	java-pkg-2_src_compile
 }

with some additional patching to build.xml:

files/tomcat-7.0.42-build.xml-extra-logging.patch 
diff --git a/build.xml b/build.xml
index 40b4d47..586f97f 100644
--- a/build.xml
+++ b/build.xml
@@ -1283,13 +1283,15 @@
   </target>
 
   <target name="extras-commons-logging"
-          depends="extras-commons-logging-prepare,compile,build-manifests"
+          depends="compile,build-manifests"
           description="Build JULI for log4j extras package">
 
+<!--
     <gunzip src="${commons-logging-src.tar.gz}"
       dest="${tomcat.extras}/logging/commons-logging-src.tar"/>
     <untar src="${tomcat.extras}/logging/commons-logging-src.tar"
       dest="${tomcat.extras}/logging/"/>
+-->
 
     <replace dir="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src/src/java/org/apache/commons"
         encoding="ISO-8859-1">
@@ -1311,12 +1313,14 @@
     <copy tofile="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src/build2.xml"
       file="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src/build.xml" />
 
+<!--
     <copy todir="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src">
       <fileset file="${avalon-framework.jar}" />
       <fileset file="${log4j.jar}" />
       <fileset file="${logkit.jar}" />
       <fileset file="${servletapi.jar}" />
     </copy>
+-->
 
     <ant antfile="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src/build2.xml"
          dir="${tomcat.extras}/logging/commons-logging-${commons-logging.version}-src"


If the commons-logging source would contain the build.xml we could possibly avoid duplicating the commons-logging patches.