📄 jkmain.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jk.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.jk.core.JkHandler;
import org.apache.jk.core.WorkerEnv;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.modeler.Registry;
/** Main class used to startup and configure jk. It manages the conf/jk2.properties file
* and is the target of JMX proxy.
*
* It implements a policy of save-on-change - whenever a property is changed at
* runtime the jk2.properties file will be overriden.
*
* You can edit the config file when tomcat is stoped ( or if you don't use JMX or
* other admin tools ).
*
* The format of jk2.properties:
* <dl>
* <dt>TYPE[.LOCALNAME].PROPERTY_NAME=VALUE
* <dd>Set a property on the associated component. TYPE will be used to
* find the class name and instantiate the component. LOCALNAME allows
* multiple instances. In JMX mode, TYPE and LOCALNAME will form the
* JMX name ( eventually combined with a 'jk2' component )
*
* <dt>NAME=VALUE
* <dd>Define global properties to be used in ${} substitutions
*
* <dt>class.COMPONENT_TYPE=JAVA_CLASS_NAME
* <dd>Adds a new 'type' of component. We predefine all known types.
* </dl>
*
* Instances are created the first time a component name is found. In addition,
* 'handler.list' property will override the list of 'default' components that are
* loaded automatically.
*
* Note that the properties file is just one (simplistic) way to configure jk. We hope
* to see configs based on registry, LDAP, db, etc. ( XML is not necesarily better )
*
* @author Costin Manolache
*/
public class JkMain implements MBeanRegistration
{
WorkerEnv wEnv;
String propFile;
Properties props=new Properties();
Properties modules=new Properties();
boolean modified=false;
boolean started=false;
boolean saveProperties=false;
public JkMain()
{
JkMain.jkMain=this;
modules.put("channelSocket", "org.apache.jk.common.ChannelSocket");
modules.put("channelNioSocket", "org.apache.jk.common.ChannelNioSocket");
modules.put("channelUnix", "org.apache.jk.common.ChannelUn");
modules.put("channelJni", "org.apache.jk.common.ChannelJni");
modules.put("apr", "org.apache.jk.apr.AprImpl");
modules.put("mx", "org.apache.jk.common.JkMX");
modules.put("modeler", "org.apache.jk.common.JkModeler");
modules.put("shm", "org.apache.jk.common.Shm");
modules.put("request","org.apache.jk.common.HandlerRequest");
modules.put("container","org.apache.jk.common.HandlerRequest");
modules.put("modjk","org.apache.jk.common.ModJkMX");
}
public static JkMain getJkMain() {
return jkMain;
}
private static String DEFAULT_HTTPS="com.sun.net.ssl.internal.www.protocol";
private void initHTTPSUrls() {
try {
// 11657: if only ajp is used, https: redirects need to work ( at least for 1.3+)
String value = System.getProperty("java.protocol.handler.pkgs");
if (value == null) {
value = DEFAULT_HTTPS;
} else if (value.indexOf(DEFAULT_HTTPS) >= 0 ) {
return; // already set
} else {
value += "|" + DEFAULT_HTTPS;
}
System.setProperty("java.protocol.handler.pkgs", value);
} catch(Exception ex ) {
log.info("Error adding SSL Protocol Handler",ex);
}
}
// -------------------- Setting --------------------
/** Load a .properties file into and set the values
* into jk2 configuration.
*/
public void setPropertiesFile( String p ) {
propFile=p;
if( started ) {
loadPropertiesFile();
}
}
public String getPropertiesFile() {
return propFile;
}
public void setSaveProperties( boolean b ) {
saveProperties=b;
}
/** Set a name/value as a jk2 property
*/
public void setProperty( String n, String v ) {
if( "jkHome".equals( n ) ) {
setJkHome( v );
}
if( "propertiesFile".equals( n ) ) {
setPropertiesFile( v );
}
props.put( n, v );
if( started ) {
processProperty( n, v );
saveProperties();
}
}
/**
* Retrieve a property.
*/
public Object getProperty(String name) {
String alias = (String)replacements.get(name);
Object result = null;
if(alias != null) {
result = props.get(alias);
}
if(result == null) {
result = props.get(name);
}
return result;
}
/**
* Set the <code>channelClassName</code> that will used to connect to
* httpd.
*/
public void setChannelClassName(String name) {
props.put( "handler.channel.className",name);
}
public String getChannelClassName() {
return (String)props.get( "handler.channel.className");
}
/**
* Set the <code>workerClassName</code> that will handle the request.
* ( sort of 'pivot' in axis :-)
*/
public void setWorkerClassName(String name) {
props.put( "handler.container.className",name);
}
public String getWorkerClassName() {
return (String)props.get( "handler.container.className");
}
/** Set the base dir of jk2. ( including WEB-INF if in a webapp ).
* We'll try to guess it from classpath if none is set ( for
* example on command line ), but if in a servlet environment
* you need to use Context.getRealPath or a system property or
* set it expliciltey.
*/
public void setJkHome( String s ) {
getWorkerEnv().setJkHome(s);
}
public String getJkHome() {
return getWorkerEnv().getJkHome();
}
String out;
String err;
File propsF;
public void setOut( String s ) {
this.out=s;
}
public String getOut() {
return this.out;
}
public void setErr( String s ) {
this.err=s;
}
public String getErr() {
return this.err;
}
// -------------------- Initialization --------------------
public void init() throws IOException
{
long t1=System.currentTimeMillis();
if(null != out) {
PrintStream outS=new PrintStream(new FileOutputStream(out));
System.setOut(outS);
}
if(null != err) {
PrintStream errS=new PrintStream(new FileOutputStream(err));
System.setErr(errS);
}
String home=getWorkerEnv().getJkHome();
if( home==null ) {
// XXX use IntrospectionUtil to find myself
this.guessHome();
}
home=getWorkerEnv().getJkHome();
if( home==null ) {
log.info( "Can't find home, jk2.properties not loaded");
}
if(log.isDebugEnabled())
log.debug("Starting Jk2, base dir= " + home );
loadPropertiesFile();
String initHTTPS = (String)props.get("class.initHTTPS");
if("true".equalsIgnoreCase(initHTTPS)) {
initHTTPSUrls();
}
long t2=System.currentTimeMillis();
initTime=t2-t1;
}
static String defaultHandlers[]= { "request",
"container",
"channelSocket"};
/*
static String defaultHandlers[]= { "apr",
"shm",
"request",
"container",
"channelSocket",
"channelJni",
"channelUnix"};
*/
public void stop()
{
for( int i=0; i<wEnv.getHandlerCount(); i++ ) {
if( wEnv.getHandler(i) != null ) {
try {
wEnv.getHandler(i).destroy();
} catch( IOException ex) {
log.error("Error stoping " + wEnv.getHandler(i).getName(), ex);
}
}
}
started=false;
}
public void start() throws IOException
{
long t1=System.currentTimeMillis();
// We must have at least 3 handlers:
// channel is the 'transport'
// request is the request processor or 'global' chain
// container is the 'provider'
// Additional handlers may exist and be used internally
// or be chained to create one of the standard handlers
String handlers[]=defaultHandlers;
// backward compat
String workers=props.getProperty( "handler.list", null );
if( workers!=null ) {
handlers= split( workers, ",");
}
// Load additional component declarations
processModules();
for( int i=0; i<handlers.length; i++ ) {
String name= handlers[i];
JkHandler w=getWorkerEnv().getHandler( name );
if( w==null ) {
newHandler( name, "", name );
}
}
// Process properties - and add aditional handlers.
processProperties();
for( int i=0; i<wEnv.getHandlerCount(); i++ ) {
if( wEnv.getHandler(i) != null ) {
try {
wEnv.getHandler(i).init();
} catch( IOException ex) {
if( "apr".equals(wEnv.getHandler(i).getName() )) {
log.info( "APR not loaded, disabling jni components: " + ex.toString());
} else {
log.error( "error initializing " + wEnv.getHandler(i).getName(), ex );
}
}
}
}
started=true;
long t2=System.currentTimeMillis();
startTime=t2-t1;
this.saveProperties();
log.info("Jk running ID=" + wEnv.getLocalId() + " time=" + initTime + "/" + startTime +
" config=" + propFile);
}
// -------------------- Usefull methods --------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -