====== [[http://tomcat.apache.org/|Tomcat application server]] ====== ===== Security ===== ==== Using LDAP server for BASIC authentication ==== In this setup we will use the office-wide LDAP authentication server to authenticate the client using HTTP basic authentication (digest will not work). First of all discover the structure of LDAP directory. You need to know the LDAP server URL, DN prefix for user and group search: $ ldapsearch -H ldap://ldap.company.org:389/ -D uid=myuid,ou=people,dc=company,dc=org -w -b 'uid=myuid,ou=people,dc=company,dc=org' dn: uid=myuid, ou=people, dc=company, dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson uid: myuid cn: Dmitry Katsubo sn: Katsubo givenname: Dmitry displayname: Dmitry Katsubo ... For group (role) search we will use the following filter: $ ldapsearch -H ldap://ldap.company.org:389/ -D uid=myuid,ou=people,dc=company,dc=org -w -b 'ou=groups,dc=company,dc=org' -s sub '(member=uid=myuid,ou=people,dc=company,dc=org)' dn: cn=subdiv5587, ou=groups, dc=company, dc=org objectclass: top objectclass: groupOfNames cn: subdiv5587 description: Subdevision 55.87 member: uid=myuid, ou=people, dc=company, dc=org ... other members ... dn: cn=div55, ou=groups, dc=company, dc=org objectclass: top objectclass: groupOfNames cn: div55 description: Devision 55 member: uid=myuid, ou=people, dc=company, dc=org ... other members ... Based on the discovered information we define in Tomcat's ''server.xml'' the following [[tomcat>realm-howto.html|realm]]((Check another Tomcat configuration example for LDAP authentication [[stackoverflow>267869|here]])): ... This combined realm uses the local user database (e.g. you want to define local Tomcat admins or application deployers) as well as the LDAP directory to authenticate. The last one applies authentication-by-binding mechanism. If want client to check the password, use ''userSearch'' + ''userSubtree'' ''[[tomcat>api/org/apache/catalina/realm/JNDIRealm.html|JNDIRealm]]'' properties. Now you can say in application's ''WEB-INF/web.xml'': ... All Pages /* GET POST dir2711 The role that is assigned to all members of Subdevision 55.87. subdiv5587 BASIC MyApplication You can define several ''''s and several ''''s in ''''. The '''' from '''' should be also described by ''''. '''' represents basic HTTP/1.1 authentication methods: * BASIC, DIGEST -- described in [[rfc>2617]] * NEGOTIATE -- described in [[rfc>4559]] * FORM -- means the credentials should be entered via HTML form defined by '''' element((See [[http://jcp.org/aboutJava/communityprocess/first/jsr154/index3.html|Java Servlet 2.4 Specification, §12.5 "Authentication"]] for more details about authentication methods and roles configuration)). In the code one can use [[javaee>api/javax/servlet/http/HttpServletRequest.html#getRemoteUser()|HttpServletRequest#getRemoteUser()]] and [[javaee>api/javax/servlet/http/HttpServletRequest.html#isUserInRole(java.lang.String)|HttpServletRequest#isUserInRole()]] methods: package org.company.application.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class MyWebController { private static final Log logger = LogFactory.getLog(MyWebController.class); @RequestMapping(value = "/processFile", method = RequestMethod.POST) public void processFile(HttpServletRequest request, HttpServletResponse response) { logger.debug("User:" + request.getRemoteUser() + ", is in directorate:" + request.isUserInRole("subdiv5587")); ... } } Let's test the above declared POST request handler: $ wget -S -nv -t 1 --post-file myfile.txt -O - http://myuid:mypasword@service-id.company.org:8080/application/processFile HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 WWW-Authenticate: Basic realm="MyApplication" Content-Type: text/html;charset=utf-8 Content-Length: 954 Date: Thu, 05 Aug 2010 16:00:40 GMT Connection: keep-alive HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/plain;charset=US-ASCII Content-Length: 3999 Date: Thu, 05 Aug 2010 16:01:09 GMT Connection: keep-alive In a log file: DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Security checking request POST /application/processFile DEBUG [org.apache.catalina.realm.RealmBase] Checking constraint 'SecurityConstraint[All Pages]' against POST /processFile --> true DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Calling hasUserDataPermission() DEBUG [org.apache.catalina.realm.RealmBase] User data constraint has no restrictions DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Calling authenticate() DEBUG [org.apache.catalina.realm.CombinedRealm] Attempting to authenticate user "myuid" with realm "org.apache.catalina.realm.UserDatabaseRealm/1.0" DEBUG [org.apache.catalina.realm.CombinedRealm] Cannot find message associated with key combinedRealm.authFail DEBUG [org.apache.catalina.realm.CombinedRealm] Attempting to authenticate user "myuid" with realm "org.apache.catalina.realm.JNDIRealm/1.0" DEBUG [org.apache.catalina.core.ContainerBase.[Catalina]] Found role: div55 DEBUG [org.apache.catalina.core.ContainerBase.[Catalina]] Found role: subdiv5587 DEBUG [org.apache.catalina.realm.CombinedRealm] Authenticated user "myuid" with realm "org.apache.catalina.realm.JNDIRealm/1.0" DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Authenticated 'myuid' with type 'BASIC' DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Calling accessControl() DEBUG [org.apache.catalina.realm.RealmBase] Checking roles GenericPrincipal[myuid(div55,subdiv5587)] DEBUG [org.apache.catalina.realm.RealmBase] Different realm org.apache.catalina.realm.CombinedRealm@1d32e45 org.apache.catalina.realm.JNDIRealm@12f1bf0 DEBUG [org.apache.catalina.realm.RealmBase] Username myuid has role subdiv5587 DEBUG [org.apache.catalina.realm.RealmBase] Role found: subdiv5587 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] Successfully passed all security constraints DEBUG [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] Mapping [/processFile] to handler 'org.company.application.web.MyWebController@24f4eb' DEBUG [org.company.application.web.MyWebController] User:myuid, is in directorate:true For more information see [[tomcat>realm-howto.html|Realm Configuration HOWTO]]. ==== Using NEGOTIATE authentication ==== General installation steps: * Create ''/etc/krb5.conf'' (or use the system-wide one, defined by Linux administrator): [libdefaults] default_realm = REALM.COMPANY.ORG default_tkt_enctypes = des-cbc-md5 des-cbc-crc default_tgs_enctypes = des-cbc-md5 des-cbc-crc kdc_timesync = 0 kdc_default_options = 0x40000010 clockskew = 300 check_delegate = 0 ccache_type = 3 kdc_timeout = 60 [domain_realm] company.org = REALM.COMPANY.ORG .company.org = REALM.COMPANY.ORG [realms] REALM.COMPANY.ORG = { admin_server = server1.company.org kdc = server1.company.org kdc = server2.company.org } * Additionally to the following [[http://spnego.sourceforge.net/spnego_tomcat.html|installation instructions]], use this: * Download the ''[[https://sourceforge.net/projects/spnego/files/|spnego.jar]]'' library and put it to ''/usr/share/tomcat6/lib'' * Add the following to ''/etc/tomcat6/web.xml'' (or to your application ''web.xml''): ... SpnegoHttpFilter net.sourceforge.spnego.SpnegoHttpFilter spnego.allow.basic true spnego.allow.localhost true spnego.allow.unsecure.basic true spnego.krb5.conf /etc/krb5.conf spnego.login.conf /etc/tomcat6/login.config spnego.login.client.module spnego-client spnego.login.server.module spnego-server spnego.prompt.ntlm true spnego.logger.level 1 SpnegoHttpFilter * * Create ''/etc/tomcat6/login.config'', which consists of two sections: ''spnego-client'' is used to authenticate service client (browser), ''spnego-server'' is used to authenticate service (Tomcat) to KDC. The service principal should be present in a given ''/etc/tomcat6/service.keytab'' and should be provided to you by KDC administrator: spnego-client { com.sun.security.auth.module.Krb5LoginModule required; }; spnego-server { com.sun.security.auth.module.Krb5LoginModule required storeKey=true useKeyTab=true keyTab="file:/etc/tomcat6/service.keytab" principal="HTTP/service-id.company.org@REALM.COMPANY.ORG"; }; * Now you can upload [[http://spnego.sourceforge.net/hello_spnego.zip|hello_spnego.jsp]] to ''/var/lib/tomcat6/webapps/ROOT'' and test by navigating to ''http://service-id.company.org:8080/hello_spnego.jsp''. ''net.sourceforge.spnego.SpnegoHttpFilter'' uses JUL to log debug information. See [[#how_to_enable_log4j_logging_for_tomcat|Questions Answered]] section for the hints about how to setup the logging environment. To setup ''net.sourceforge.spnego.SpnegoHttpFilter'' for Jetty, refer [[http://wiki.openbluedragon.org/wiki/index.php/Jetty:ConfiguringSSO|Configuring SSO on Jetty 6]]. The only thing to add to above settings is the following: REALM.COMPANY.ORG spnego-client For Jetty see [[jetty#how_to_configure_jetty_to_use_spnegonegotiate_authentication|How to configure Jetty to use SPNEGO/NEGOTIATE authentication]]. \\ For local services development, follow [[conflepo>RNA/spnego-Tomcat|SPNEGO Tomcat instructions]]: * Upload ''xxx-spnego-1.1.20.jar''((Provides ''XmiRoleMappingLoginModule'' module, that is responsible for mapping users to security roles using the mapping file ''application-bnd.xmi'')), ''xxx-spnego-tomcat-1.1.20.jar'', ''xxx_common_Jaas-0.3.3.jar'', ''xxx-spnego-pac-1.1.20.jar''((Provides the support of [[http://appliedcrypto.com/spnego/pac/ms_kerberos_pac.html|Microsoft Kerberos Extension called PAC]] (Privilege Attribute Certificate))), ''[[http://mirrors.ibiblio.org/pub/mirrors/maven2/bouncycastle/bcprov-jdk16/140/bcprov-jdk16-140.jar|bcprov-jdk16-1.40.jar]]''(([[http://www.bouncycastle.org/|Bouncy Castle Crypto]] package -- a Java implementation of cryptographic symmetric block algorithms (AES, Blowfish, CASTx, DES, IDEA, RCx, Rijndael, ...), symmetric stream algorithms (RC4, HCx, Grain, ...), asymmetric block algorithms (OAEP, PCKS1, ...) and digest algorithms(MDx, SHAx, RipeMD, Tiger, ...))), ''commons-logging-1.1.1.jar'' libraries to ''/usr/share/tomcat6/lib''. * Create ''/etc/tomcat6/login.config'', which consists of two sections: ''app.spnego.client'' is used to authenticate service client (browser), ''app.spnego.server'' is used to authenticate service (Tomcat) to KDC. The service principal should be present in a given ''/etc/tomcat6/service.keytab'' and should be provided to you by KDC administrator: // SPNEGO setup to authenticate the client. Should match context.xml/Context/Realm[className='org.company.security.tomcat.SpnegoRealm']/@AppName: app.spnego.client { org.company.security.sso.spnego.SpnegoLoginModule required; // org.company.security.sso.spnego.XmiRoleMappingLoginModule optional // additionalRoles="additionalRoleA,additionalRoleB,Authenticated"; }; // SPNEGO setup to authenticate the sevice to KDC. // The given keytab should correspond to principal name and should be registered at KDC. app.spnego.server { com.sun.security.auth.module.Krb5LoginModule required principal="HTTP/service-id.company.org@REALM.COMPANY.ORG" useKeyTab=true keyTab="/etc/tomcat6/service.keytab" storeKey=true debug=true; }; * Create ''/etc/tomcat6/spnego.properties'' that should contain the references to ''login.config'' and ''krb5.conf''. This file is read by ''xxx-spnego-1.1.20.jar'': java.security.auth.login.config=/etc/tomcat6/login.config java.security.krb5.conf=/etc/krb5.conf jaas.kerberos.config.name=app.spnego.server # Settings below are optional and required for users-to-roles mappings. You need to enable XmiRoleMappingLoginModule in login.config. #xxx.ldap.url=ldap://server1.company.org:389/dc=company,dc=org #bindings.file.name=/etc/tomcat6/application-bnd.xmi #roles.file.name=conf/etc/tomcat6/application.xml * Include ''/etc/tomcat6/spnego.properties'' into server ''JAVA_OPTS'': # Enable SPNEGO JAVA_OPTS="${JAVA_OPTS} -Dspnego.config=/etc/tomcat6/spnego.properties" * Modify '''' of application's ''WEB-INF/web.xml'': ... ... * NEGOTIATE MyApplication * Create application ''META-INF/context.xml'' or modify server-wide '''': * :OPT: Create ''/etc/tomcat6/application-bnd.xmi'' and ''/etc/tomcat6/application.xml'' to customize the mapping between LDAP groups and Web Container roles: My Enterprise Application My Service myservice.war production/myservice System Administrator SYSADMIN Online Operator OPERATOR All Authenticated Users AUTHENTICATED_USER ===== Questions answered ===== === Tomcat cannot start due to ''java.net.SocketException'' === The following error is in server log file: SEVERE: StandardServer.await: create[8005]: java.net.SocketException: Invalid argument at java.net.PlainSocketImpl.socketBind(Native Method) at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365) at java.net.ServerSocket.bind(ServerSocket.java:319) at java.net.ServerSocket.(ServerSocket.java:185) at org.apache.catalina.core.StandardServer.await(StandardServer.java:373) at org.apache.catalina.startup.Catalina.await(Catalina.java:662) at org.apache.catalina.startup.Catalina.start(Catalina.java:614) 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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Start your JVM with ''-Djava.net.preferIPv4Stack=true'' (see [[javase>/docs/guide/net/properties.html|Java Networking Properties]]) or set ''net.ipv6.bindv6only'' kernel system variable to zero (see [[http://lists-archives.org/debian-user/3550442-tomcat-is-only-listening-with-ip6-and-not-ip4.html|this conversion]]): # This sysctl sets the default value of the IPV6_V6ONLY socket option. # # When disabled, IPv6 sockets will also be able to send and receive IPv4 # traffic with addresses in the form ::ffff:192.0.2.1 and daemons listening # on IPv6 sockets will also accept IPv4 connections. # # When IPV6_V6ONLY is enabled, daemons interested in both IPv4 and IPv6 # connections must open two listening sockets. # This is the default behaviour of all modern operating systems. net.ipv6.bindv6only = 0 === The form fields values submitted by a browser are not correctly UTF-8 encoded === From [[apache>tomcat/FAQ/CharacterEncoding|Character Encoding Issues]]: For correct UTF-8 URL handling set ''%%'' option in ''server.xml'' or use ''%%''. The contents (request body) is not correctly represented because by default the character encoding of ''HttpServletRequest'' is set to ISO-8859-1 (unless is provided in browser request). Spring has a special ''CharacterEncodingFilter'' filter that fixes this (see sample [[stackoverflowa>3228524/267197|here]]). === ''Unable to add the resource at [/...] to the cache for web application [/app] because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache'' === To fix this add: ... === How to specify the context path for application deployment in Tomcat? === Before Tomcat 6 the context path could have been specified in ''META-INF/context.xml'' however this behaviour has changed in Tomcat 6 (see [[http://tomcat.apache.org/tomcat-6.0-doc/config/context.html|Context Container]], [[apachebztracker>46713|bug#46713]] and [[stackoverflow>6623586|Tomcat's context path for a webapp not working]]):
''path'' attribute must only be used when statically defining a Context in ''server.xml''. In all other circumstances, the path will be inferred from the filenames used for either the .xml context file or the ''docBase''.
For deployment to Tomcat 6 you should use ''tomcat-maven-plugin'' (that deploys via [[http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html|Tomcat Manager]]): org.codehaus.mojo tomcat-maven-plugin tomcat-server-id ${tomcat.server.url}/manager ${context.path}
=== Why ImageIO library does not work when deployed to Tomcat AS? === The problem is correctly described in [[https://bugs.launchpad.net/goobi-production/+bug/788160/comments/13|comment #13 for bug 788160 (Error reading in TIFF images)]]: Tomcat has build-in [[http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html#JRE_Memory_Leak_Prevention_Listener_-_org.apache.catalina.core.JreMemoryLeakPreventionListener|memory leak protections]], one of which does not allow to automatically image providers from web application in JVM-wide ImageIO registry. This is done by [[grepcode>repo1.maven.org/maven2/org.apache.tomcat/tomcat-catalina/7.0.0/org/apache/catalina/core/JreMemoryLeakPreventionListener.java#139|JreMemoryLeakPreventionListener]] which initializes ImageIO (call to any static method forces static registry to be initialized). As a workaround ''appContextProtection'' has to be disabled for ''JreMemoryLeakPreventionListener'': however this is not a complete solution as if application is redeployed again and again, the references to image providers will still be kept together with classloader and all classes it has loaded. This will cause [[https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation|PermGen]] to run out of memory and under certain conditions may cause [[https://groups.google.com/forum/#!msg/google-web-toolkit/QvduX97Swfg/Bv1V4NPI03cJ|ClassCastException when using ImageIO]]. One solution is provided in ''[[https://github.com/haraldk/TwelveMonkeys/blob/master/servlet/src/main/java/com/twelvemonkeys/servlet/image/IIOProviderContextListener.java|IIOProviderContextListener.java]]'' (see [[stackoverflowa>17365294/267197|How to resolve OutOfMemoryError with ImageIO plugins as the cause]]), and basically consists of the following steps: * Web application needs to call ''ImageIO.scanForPlugins()'' before using any ImageIO API (servlet initialization). * On destruction, web application needs to deregister providers loaded from web application classpath. Another solution is to put ''jai_imageio.jar'' + ''jai_codec.jar'' into server-wide ''lib/'' folder. References: * [[stackoverflowa>18141946/267197|My Java SPI extension is not loaded]] * [[http://tomcat.10.x6.nabble.com/Problems-with-ImageIO-td2073212.html#a2073223|ImageIO.getImageReadersByFormatName("tiff") returns false for hasNext()]] * [[http://thejavashop.net/blog/?p=27|JAI Imaging and Tomcat]] === How to enable ''log4j'' logging for Tomcat? === See steps [[tomcat>logging.html#log4j|here]]. Recommended Log4j configuration: log4j.rootLogger=INFO, R log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=${catalina.base}/logs/tomcat.log log4j.appender.R.MaxFileSize=50MB log4j.appender.R.MaxBackupIndex=5 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%d{dd.MM HH:mm:ss} %-5p [%c] %m%n # For a more detailed Catalina localhost log, uncomment below: #log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG #log4j.logger.org.apache.catalina.core=DEBUG #log4j.logger.org.apache.catalina.session=DEBUG If you remove ''/etc/tomcat6/logging.properties'' file you will not be able to see the debug output done via ''java.util.logging''. So either keep it, or remove/rename and continue with steps below. Also you might be interested in redirecting the ''java.util.logging'' to Log4j completely so you don't need to dig two log files for errors as everything will be in one file. For that you need to do further steps to one mentioned above: * Download [[http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/intro.html|jul-log4j-bridge]] from [[http://people.apache.org/~psmith/logging.apache.org/repo/org/apache/logging/apache-jul-log4j-bridge/1.0.0-SNAPSHOT/apache-jul-log4j-bridge-1.0.0-20080915.045446-7.jar|here]] and put it to ''/usr/share/tomcat6/lib''. * Make sure you have [[http://logging.apache.org/log4j/|Log4j]] implementation (e.g. ''log4j-1.2.15.jar'') in ''/usr/share/tomcat6/lib''. * Include ''apache-jul-log4j-bridge.jar'', ''log4j-1.2.15.jar'' and ''log4j.properties'' directory location into Tomcat boot classpath: --- catalina.sh.orig 2010-06-14 21:21:36.000000000 +0200 +++ catalina.sh 2010-08-09 13:06:38.000000000 +0200 @@ -164,12 +164,17 @@ # Add tomcat-juli.jar and bootstrap.jar to classpath # tomcat-juli.jar can be over-ridden per instance if [ ! -z "$CLASSPATH" ] ; then - CLASSPATH="$CLASSPATH": + CLASSPATH="$CLASSPATH:" fi -if [ "$CATALINA_BASE" != "$CATALINA_HOME" ] && [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then - CLASSPATH="$CLASSPATH""$CATALINA_BASE"/bin/tomcat-juli.jar:"$CATALINA_HOME"/bin/bootstrap.jar -else - CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar + +CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar + +if [ "$CATALINA_BASE" != "$CATALINA_HOME" ] && [ -r "$CATALINA_HOME/bin/tomcat-juli.jar" ] ; then + CLASSPATH="$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar" +fi + +if [ -r "$CATALINA_HOME/lib/apache-jul-log4j-bridge.jar" -a -r "$CATALINA_HOME/lib/log4j-1.2.15.jar" ] ; then + CLASSPATH="$CLASSPATH:$CATALINA_HOME/lib/apache-jul-log4j-bridge.jar:$CATALINA_HOME/lib/log4j-1.2.15.jar:$CATALINA_HOME/lib" fi if [ -z "$CATALINA_OUT" ] ; then * Override ''java.util.logging.manager'' property either via ''LOGGING_MANAGER'' or ''JAVA_OPTS'' (check your startup scripts and ''catalina.sh'' about how to do it correctly): LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager" * If you install Tomcat on SuSE from rpm, instead of fixing ''catalina.sh'' you need to fix ''/etc/init.d/tomcat6'' (or ''/usr/sbin/dtomcat6''): --- /usr/bin/dtomcat6.orig 2011-02-22 23:20:16.000000000 +0100 +++ /usr/bin/dtomcat6 2011-12-12 10:29:12.000000000 +0100 @@ -24,6 +25,9 @@ fi CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/bin/bootstrap.jar" CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/bin/tomcat-juli.jar" +CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/lib/apache-jul-log4j-bridge.jar" +CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/lib/log4j-1.2.15.jar" +CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/lib" CLASSPATH="${CLASSPATH}:$(build-classpath commons-daemon 2>/dev/null)" if [ "$1" = "start" ]; then @@ -34,7 +38,7 @@ -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \ -Djava.io.tmpdir="$CATALINA_TMPDIR" \ -Djava.util.logging.config.file="${CATALINA_BASE}/conf/logging.properties" \ - -Djava.util.logging.manager="org.apache.juli.ClassLoaderLogManager" \ + -Djava.util.logging.manager="org.apache.logging.julbridge.JULBridgeLogManager" \ org.apache.catalina.startup.Bootstrap start \ >> ${CATALINA_BASE}/logs/catalina.out 2>&1 & if [ ! -z "$CATALINA_PID" ]; then Finally, checklist: * ''/usr/share/tomcat6/bin'' contains: * ''catalina.sh'' (//patched for classpath//) * ''tomcat-juli.jar'' (//from [[http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.32/bin/extras/|extras]]//) * ''/usr/share/tomcat6/lib'' contains: * ''tomcat-juli-adapters.jar'' (//from [[http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.32/bin/extras/|extras]]//) * ''log4j.properties'' (//newly created//) * ''log4j-1.2.15.jar'' * ''apache-jul-log4j-bridge.jar'' * ''/etc/default/tomcat6'' is fixed for ''LOGGING_MANAGER''. and you are ready to restart Tomcat and enjoy the result. For slf4j logging, check [[github>grgrzybek/tomcat-slf4j-logback|here]]. === Quick deployment of Web application === See [[habrahabr>126066|Быстрая разработка веб-приложений на Java]]: * [[maven#how_can_i_run_embedded_web_container|Jetty Maven plugin]] / [[http://www.gradle.org/jetty_plugin.html|Jetty Gradle plugin]] / [[googlecode>p/run-jetty-run/|Run Jetty Run]] * [[http://www.eclipsetotale.com/tomcatPlugin.html|Eclipse Tomcat Launcher plugin]] / [[http://www.eclipse.org/webtools/|Eclipse WTP]] * [[http://www.springsource.com/developer/sts|Springsource tool suite]] === Tomcat/Jetty remote JMX monitoring of JVM state === See [[habrahabr>147008|Рецепт настройки удалённого мониторинга контейнеров Tomcat и Jetty штатными средствами JDK]]. === Enabling HTTP/2 === Several resposes from ''mod_jk'' could not be multiplexed into one HTTP/2 stream, see [[stackoverflowa>35705569/267197|this post]]. To enable multiplexing JBoss 5.x / [[http://tomcat.apache.org/whichversion.html#Apache_Tomcat_9.x|Apache Tomcat 9]] is required. There could be [[stackoverflowa>48103841/267197|different options where to offload TLS]]: * Decrypt traffic and re-encrypt it for backend (''%%ProxyPass "/path" "h2://jboss.server"%%'' + '''' inside TLS enabled '''' element). * Decrypt traffic and send it plaintext to backend (''%%ProxyPass "/path" "h2c://jboss.server"%%'' + '''' inside '''' element). See also: * [[https://httpd.apache.org/docs/trunk/mod/mod_proxy_http2.html#examples|mod_proxy_http2 examples]] * [[https://tomcat.apache.org/tomcat-9.0-doc/config/http2.html|HTTP2 Upgrade Protocol]] {{tag>Tomcat Jetty LDAP SPNEGO NTLM Kerberos JIRA Confluence Spring UTF}}