From: markt Date: Sat, 7 Mar 2009 18:32:40 +0000 (+0000) Subject: Remove jk jni code from Tomcat 7. It is deprecated in mod_jk and will almost certainl... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=4bd18986f6b5ac83aa838acef87f6ee4ade5475e;p=tomcat7.0 Remove jk jni code from Tomcat 7. It is deprecated in mod_jk and will almost certainly have been rmeoved by the time 7.0.x has a stable release. Shout if I deleted something I shouldn't have. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@751303 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/jk/apr/AprImpl.java b/java/org/apache/jk/apr/AprImpl.java deleted file mode 100644 index bb4038f1b..000000000 --- a/java/org/apache/jk/apr/AprImpl.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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.apr; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Hashtable; -import org.apache.jk.core.JkHandler; -import org.apache.jk.core.MsgContext; -import org.apache.jk.core.JkChannel; - -/** Implements the interface with the APR library. This is for internal-use - * only. The goal is to use 'natural' mappings for user code - for example - * java.net.Socket for unix-domain sockets, etc. - * - */ -public class AprImpl extends JkHandler { // This will be o.a.t.util.handler.TcHandler - lifecycle and config - static AprImpl aprSingleton=null; - - String baseDir; - String aprHome; - String soExt="so"; - - static boolean ok=true; - boolean initialized=false; - // Handlers for native callbacks - Hashtable jkHandlers= new Hashtable(); - - // Name of the so used in inprocess mode - String jniModeSo="inprocess"; - // name of the so used by java. If not set we'll loadLibrary("jkjni" ), - // if set we load( nativeSo ) - String nativeSo; - - public AprImpl() { - aprSingleton=this; - } - - // -------------------- Properties -------------------- - - /** Native libraries are located based on base dir. - * XXX Add platform, version, etc - */ - public void setBaseDir(String s) { - baseDir=s; - } - - public void setSoExt(String s ) { - soExt=s; - } - - // XXX maybe install the jni lib in apr-home ? - public void setAprHome( String s ) { - aprHome=s; - } - - /** Add a Handler for jni callbacks. - */ - public void addJkHandler(String type, JkHandler cb) { - jkHandlers.put( type, cb ); - } - - /** Name of the so used in inprocess mode - */ - public void setJniModeSo(String jniModeSo ) { - this.jniModeSo=jniModeSo; - } - - /** name of the so used by java. If not set we'll loadLibrary("jkjni" ), - if set we load( nativeSo ) - */ - public void setNativeSo( String nativeSo ) { - this.nativeSo=nativeSo; - } - - /** Sets the System.out stream */ - - public static void setOut( String filename ) { - try{ - if( filename !=null ){ - System.setOut( new PrintStream(new FileOutputStream(filename ))); - } - }catch (Throwable th){ - } - } - /** Sets the System.err stream */ - - public static void setErr( String filename ) { - try{ - if( filename !=null ){ - System.setErr( new PrintStream(new FileOutputStream(filename ))); - } - }catch (Throwable th){ - } - } - - // -------------------- Apr generic utils -------------------- - /** Initialize APR - */ - public native int initialize(); - - public native int terminate(); - - /* -------------------- Access to the jk_env_t -------------------- */ - - /* The jk_env_t provide temporary storage ( pool ), logging, common services - */ - - /* Return a jk_env_t, used to keep the execution context ( temp pool, etc ) - */ - public native long getJkEnv(); - - /** Clean the temp pool, put back the env in the pool - */ - public native void releaseJkEnv(long xEnv); - - /* -------------------- Interface to the jk_bean object -------------------- */ - /* Each jk component is 'wrapped' as a bean, with a specified lifecycle - * - */ - - /** Get a native component - * @return 0 if the component is not found. - */ - public native long getJkHandler(long xEnv, String compName ); - - public native long createJkHandler(long xEnv, String compName ); - - public native int jkSetAttribute( long xEnv, long componentP, String name, String val ); - - public native String jkGetAttribute( long xEnv, long componentP, String name ); - - public native int jkInit( long xEnv, long componentP ); - - public native int jkDestroy( long xEnv, long componentP ); - - /** Send the packet to the C side. On return it contains the response - * or indication there is no response. Asymetrical because we can't - * do things like continuations. - */ - public static native int jkInvoke(long xEnv, long componentP, long endpointP, - int code, byte data[], int off, int len, int raw); - - /** Recycle an endpoint after use. - */ - public native void jkRecycle(long xEnv, long endpointP); - - // -------------------- Called from C -------------------- - // XXX Check security, add guard or other protection - // It's better to do it the other way - on init 'push' AprImpl into - // the native library, and have native code call instance methods. - - public static Object createJavaContext(String type, long cContext) { - // XXX will be an instance method, fields accessible directly - AprImpl apr=aprSingleton; - JkChannel jkH=(JkChannel)apr.jkHandlers.get( type ); - if( jkH==null ) return null; - - MsgContext ep=jkH.createMsgContext(); - - ep.setSource( jkH ); - - ep.setJniContext( cContext ); - return ep; - } - - /** Return a buffer associated with the ctx. - */ - public static byte[] getBuffer( Object ctx, int id ) { - return ((MsgContext)ctx).getBuffer( id ); - } - - public static int jniInvoke( long jContext, Object ctx ) { - try { - MsgContext ep=(MsgContext)ctx; - ep.setJniEnv( jContext ); - ep.setType( 0 ); - return ((MsgContext)ctx).execute(); - } catch( Throwable ex ) { - ex.printStackTrace(); - return -1; - } - } - - // -------------------- Initialization -------------------- - - public void init() throws IOException { - try { - initialized=true; - loadNative(); - - initialize(); - jkSetAttribute(0, 0, "channel:jni", "starting"); - - log.info("JK: Initialized apr" ); - - } catch( Throwable t ) { - throw new IOException( t.toString() ); - } - ok=true; - } - - public boolean isLoaded() { - if( ! initialized ) { - try { - init(); - } catch( Throwable t ) { - log.info("Apr not loaded: " + t); - } - } - return ok; - } - - static boolean jniMode=false; - - - public static void jniMode() { - jniMode=true; - } - - /** This method of loading the libs doesn't require setting - * LD_LIBRARY_PATH. Assuming a 'right' binary distribution, - * or a correct build all files will be in their right place. - * - * The burden is on our code to deal with platform specific - * extensions and to keep the paths consistent - not easy, but - * worth it if it avoids one extra step for the user. - * - * Of course, this can change to System.load() and putting the - * libs in LD_LIBRARY_PATH. - */ - public void loadNative() throws Throwable { - if( aprHome==null ) - aprHome=baseDir; - - // XXX Update for windows - if( jniMode ) { - /* In JNI mode we use mod_jk for the native functions. - This seems the cleanest solution that works with multiple - VMs. - */ - if (jniModeSo.equals("inprocess")) { - ok=true; - return; - } - try { - log.info("Loading " + jniModeSo); - if( jniModeSo!= null ) System.load( jniModeSo ); - } catch( Throwable ex ) { - // ignore - //ex.printStackTrace(); - return; - } - ok=true; - return; - } - - /* - jkjni _must_ be linked with apr and crypt - - this seem the only ( decent ) way to support JDK1.4 and - JDK1.3 at the same time - try { - System.loadLibrary( "crypt" ); - } catch( Throwable ex ) { - // ignore - ex.printStackTrace(); - } - try { - System.loadLibrary( "apr" ); - } catch( Throwable ex ) { - System.out.println("can't load apr, that's fine"); - ex.printStackTrace(); - } - */ - try { - if( nativeSo == null ) { - // This will load libjkjni.so or jkjni.dll in LD_LIBRARY_PATH - log.debug("Loading jkjni from " + System.getProperty("java.library.path")); - System.loadLibrary( "jkjni" ); - } else { - System.load( nativeSo ); - } - } catch( Throwable ex ) { - ok=false; - //ex.printStackTrace(); - throw ex; - } - } - - public void loadNative(String libPath) { - try { - System.load( libPath ); - } catch( Throwable ex ) { - ok=false; - if( log.isDebugEnabled() ) - log.debug( "Error loading native library ", ex); - } - } - private static org.apache.juli.logging.Log log= - org.apache.juli.logging.LogFactory.getLog( AprImpl.class ); -} diff --git a/java/org/apache/jk/apr/TomcatStarter.java b/java/org/apache/jk/apr/TomcatStarter.java deleted file mode 100644 index 65ab02571..000000000 --- a/java/org/apache/jk/apr/TomcatStarter.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.apr; - -import java.lang.reflect.Method; - -// Hack for Catalina 4.1 who hungs the calling thread. -// Also avoids delays in apache initialization ( tomcat can take a while ) - -/** - * Start some tomcat. - * - */ -public class TomcatStarter implements Runnable { - Class c; - String args[]; - AprImpl apr = new AprImpl(); - - public static String mainClasses[]={ "org.apache.tomcat.startup.Main", - "org.apache.catalina.startup.BootstrapService", - "org.apache.catalina.startup.Bootstrap"}; - - // If someone has time - we can also guess the classpath and do other - // fancy guessings. - - public static void main( String args[] ) { - System.err.println("TomcatStarter: main()"); - int nClasses = 0; - - try { - AprImpl.jniMode(); - // Find the class - Class c=null; - for( int i=0; i c, String args[] ) { - this.c=c; - this.args=args; - } - - public void run() { - System.err.println("Starting " + c.getName()); - try { - Class argClass=args.getClass(); - Method m=c.getMethod( "main", new Class[] {argClass} ); - m.invoke( c, new Object[] { args } ); - System.out.println("TomcatStarter: Done"); - if (apr.isLoaded()) - apr.jkSetAttribute(0, 0, "channel:jni", "done"); - if (args[0].equals("stop")) { - Thread.sleep(5000); - Runtime.getRuntime().exit(0); - } - } catch( Throwable t ) { - t.printStackTrace(System.err); - } - } -} diff --git a/java/org/apache/jk/common/ChannelJni.java b/java/org/apache/jk/common/ChannelJni.java deleted file mode 100644 index 6a323fec6..000000000 --- a/java/org/apache/jk/common/ChannelJni.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.common; - -import java.io.IOException; - -import org.apache.jk.core.JkHandler; -import org.apache.jk.core.Msg; -import org.apache.jk.core.MsgContext; -import org.apache.jk.core.JkChannel; - -import org.apache.coyote.Request; -/** Pass messages using jni - * - * @author Costin Manolache - */ -public class ChannelJni extends JniHandler implements JkChannel { - int receivedNote=1; - - public ChannelJni() { - // we use static for now, it's easier on the C side. - // Easy to change after we get everything working - } - - public void init() throws IOException { - super.initNative("channel.jni:jni"); - - if( apr==null ) return; - - // We'll be called from C. This deals with that. - apr.addJkHandler( "channelJni", this ); - log.info("JK: listening on channel.jni:jni" ); - - if( next==null ) { - if( nextName!=null ) - setNext( wEnv.getHandler( nextName ) ); - if( next==null ) - next=wEnv.getHandler( "dispatch" ); - if( next==null ) - next=wEnv.getHandler( "request" ); - if( log.isDebugEnabled() ) - log.debug("Setting default next " + next.getClass().getName()); - } - } - - /** Receives does nothing - send will put the response - * in the same buffer - */ - public int receive( Msg msg, MsgContext ep ) - throws IOException - { - Msg sentResponse=(Msg)ep.getNote( receivedNote ); - ep.setNote( receivedNote, null ); - - if( sentResponse == null ) { - if( log.isDebugEnabled() ) - log.debug("No send() prior to receive(), no data buffer"); - // No sent() was done prior to receive. - msg.reset(); - msg.end(); - sentResponse = msg; - } - - sentResponse.processHeader(); - - if( log.isTraceEnabled() ) - sentResponse.dump("received response "); - - if( msg != sentResponse ) { - log.error( "Error, in JNI mode the msg used for receive() must be identical with the one used for send()"); - } - - return 0; - } - - /** Send the packet. XXX This will modify msg !!! - * We could use 2 packets, or sendAndReceive(). - * - */ - public int send( Msg msg, MsgContext ep ) - throws IOException - { - ep.setNote( receivedNote, null ); - if( log.isDebugEnabled() ) log.debug("ChannelJni.send: " + msg ); - - int rc=super.nativeDispatch( msg, ep, JK_HANDLE_JNI_DISPATCH, 0); - - // nativeDispatch will put the response in the same buffer. - // Next receive() will just get it from there. Very tricky to do - // things in one thread instead of 2. - ep.setNote( receivedNote, msg ); - - return rc; - } - - public int flush(Msg msg, MsgContext ep) throws IOException { - ep.setNote( receivedNote, null ); - return OK; - } - - public boolean isSameAddress(MsgContext ep) { - return true; - } - - public void registerRequest(Request req, MsgContext ep, int count) { - // Not supported. - } - - public String getChannelName() { - return getName(); - } - /** Receive a packet from the C side. This is called from the C - * code using invocation, but only for the first packet - to avoid - * recursivity and thread problems. - * - * This may look strange, but seems the best solution for the - * problem ( the problem is that we don't have 'continuation' ). - * - * sendPacket will move the thread execution on the C side, and - * return when another packet is available. For packets that - * are one way it'll return after it is processed too ( having - * 2 threads is far more expensive ). - * - * Again, the goal is to be efficient and behave like all other - * Channels ( so the rest of the code can be shared ). Playing with - * java objects on C is extremely difficult to optimize and do - * right ( IMHO ), so we'll try to keep it simple - byte[] passing, - * the conversion done in java ( after we know the encoding and - * if anyone asks for it - same lazy behavior as in 3.3 ). - */ - public int invoke(Msg msg, MsgContext ep ) throws IOException { - if( apr==null ) return -1; - - long xEnv=ep.getJniEnv(); - - int type=ep.getType(); - if( log.isDebugEnabled() ) log.debug("ChannelJni.invoke: " + ep + " " + type); - - switch( type ) { - case JkHandler.HANDLE_RECEIVE_PACKET: - return receive( msg, ep ); - case JkHandler.HANDLE_SEND_PACKET: - return send( msg, ep ); - case JkHandler.HANDLE_FLUSH: - return flush(msg, ep); - } - - // Reset receivedNote. It'll be visible only after a SEND and before a receive. - ep.setNote( receivedNote, null ); - - // Default is FORWARD - called from C - try { - // first, we need to get an endpoint. It should be - // per/thread - and probably stored by the C side. - if( log.isDebugEnabled() ) log.debug("Received request " + xEnv); - - // The endpoint will store the message pt. - msg.processHeader(); - - if( log.isTraceEnabled() ) msg.dump("Incoming msg "); - - int status= next.invoke( msg, ep ); - - if( log.isDebugEnabled() ) log.debug("after processCallbacks " + status); - - return status; - } catch( Exception ex ) { - ex.printStackTrace(); - } - return 0; - } - - private static org.apache.juli.logging.Log log= - org.apache.juli.logging.LogFactory.getLog( ChannelJni.class ); - -} diff --git a/java/org/apache/jk/common/ChannelShm.java b/java/org/apache/jk/common/ChannelShm.java deleted file mode 100644 index bebb3fa4d..000000000 --- a/java/org/apache/jk/common/ChannelShm.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.common; - -import org.apache.jk.core.JkHandler; - - - -/** Channel using shm. - * - * @author Costin Manolache - */ -public class ChannelShm extends JkHandler { - - // Not implemented yet. - - -} diff --git a/java/org/apache/jk/common/ChannelUn.java b/java/org/apache/jk/common/ChannelUn.java deleted file mode 100644 index ceab769d1..000000000 --- a/java/org/apache/jk/common/ChannelUn.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * 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.common; - -import java.net.URLEncoder; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import javax.management.ObjectName; - -import org.apache.jk.core.JkHandler; -import org.apache.jk.core.Msg; -import org.apache.jk.core.MsgContext; -import org.apache.jk.core.JkChannel; -import org.apache.jk.core.WorkerEnv; -import org.apache.coyote.Request; -import org.apache.coyote.RequestGroupInfo; -import org.apache.coyote.RequestInfo; -import org.apache.tomcat.util.modeler.Registry; -import org.apache.tomcat.util.threads.ThreadPool; -import org.apache.tomcat.util.threads.ThreadPoolRunnable; - - -/** Pass messages using unix domain sockets. - * - * @author Costin Manolache - */ -public class ChannelUn extends JniHandler implements JkChannel { - static final int CH_OPEN=4; - static final int CH_CLOSE=5; - static final int CH_READ=6; - static final int CH_WRITE=7; - - String file; - ThreadPool tp = ThreadPool.createThreadPool(true); - - /* ==================== Tcp socket options ==================== */ - - public ThreadPool getThreadPool() { - return tp; - } - - public void setFile( String f ) { - file=f; - } - - public String getFile() { - return file; - } - - /* ==================== ==================== */ - int socketNote=1; - int isNote=2; - int osNote=3; - - int localId=0; - - public void init() throws IOException { - if( file==null ) { - log.debug("No file, disabling unix channel"); - return; - //throw new IOException( "No file for the unix socket channel"); - } - if( wEnv!=null && wEnv.getLocalId() != 0 ) { - localId=wEnv.getLocalId(); - } - - if( localId != 0 ) { - file=file+ localId; - } - File socketFile=new File( file ); - if( !socketFile.isAbsolute() ) { - String home=wEnv.getJkHome(); - if( home==null ) { - log.debug("No jkhome"); - } else { - File homef=new File( home ); - socketFile=new File( homef, file ); - log.debug( "Making the file absolute " +socketFile); - } - } - - if( ! socketFile.exists() ) { - try { - FileOutputStream fos=new FileOutputStream(socketFile); - fos.write( 1 ); - fos.close(); - } catch( Throwable t ) { - log.error("Attempting to create the file failed, disabling channel" - + socketFile); - return; - } - } - // The socket file cannot be removed ... - if (!socketFile.delete()) { - log.error( "Can't remove socket file " + socketFile); - return; - } - - - super.initNative( "channel.un:" + file ); - - if( apr==null || ! apr.isLoaded() ) { - log.debug("Apr is not available, disabling unix channel "); - apr=null; - return; - } - - // Set properties and call init. - setNativeAttribute( "file", file ); - // unixListenSocket=apr.unSocketListen( file, 10 ); - - setNativeAttribute( "listen", "10" ); - // setNativeAttribute( "debug", "10" ); - - // Initialize the thread pool and execution chain - if( next==null && wEnv!=null ) { - if( nextName!=null ) - setNext( wEnv.getHandler( nextName ) ); - if( next==null ) - next=wEnv.getHandler( "dispatch" ); - if( next==null ) - next=wEnv.getHandler( "request" ); - } - - super.initJkComponent(); - JMXRequestNote =wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "requestNote"); - // Run a thread that will accept connections. - if( this.domain != null ) { - try { - tpOName=new ObjectName(domain + ":type=ThreadPool,name=" + - getChannelName()); - - Registry.getRegistry(null, null) - .registerComponent(tp, tpOName, null); - - rgOName = new ObjectName - (domain+":type=GlobalRequestProcessor,name=" + getChannelName()); - Registry.getRegistry(null, null) - .registerComponent(global, rgOName, null); - } catch (Exception e) { - log.error("Can't register threadpool" ); - } - } - tp.start(); - AprAcceptor acceptAjp=new AprAcceptor( this ); - tp.runIt( acceptAjp); - log.info("JK: listening on unix socket: " + file ); - - } - - ObjectName tpOName; - ObjectName rgOName; - RequestGroupInfo global=new RequestGroupInfo(); - int count = 0; - int JMXRequestNote; - - public void start() throws IOException { - } - - public void destroy() throws IOException { - if( apr==null ) return; - try { - if( tp != null ) - tp.shutdown(); - - //apr.unSocketClose( unixListenSocket,3); - super.destroyJkComponent(); - - if(tpOName != null) { - Registry.getRegistry(null, null).unregisterComponent(tpOName); - } - if(rgOName != null) { - Registry.getRegistry(null, null).unregisterComponent(rgOName); - } - } catch(Exception e) { - log.error("Error in destroy",e); - } - } - - public void registerRequest(Request req, MsgContext ep, int count) { - if(this.domain != null) { - try { - - RequestInfo rp=req.getRequestProcessor(); - rp.setGlobalProcessor(global); - ObjectName roname = new ObjectName - (getDomain() + ":type=RequestProcessor,worker="+ - getChannelName()+",name=JkRequest" +count); - ep.setNote(JMXRequestNote, roname); - - Registry.getRegistry(null, null).registerComponent( rp, roname, null); - } catch( Exception ex ) { - log.warn("Error registering request"); - } - } - } - - - /** Open a connection - since we're listening that will block in - accept - */ - public int open(MsgContext ep) throws IOException { - // Will associate a jk_endpoint with ep and call open() on it. - // jk_channel_un will accept a connection and set the socket info - // in the endpoint. MsgContext will represent an active connection. - return super.nativeDispatch( ep.getMsg(0), ep, CH_OPEN, 1 ); - } - - public void close(MsgContext ep) throws IOException { - super.nativeDispatch( ep.getMsg(0), ep, CH_CLOSE, 1 ); - } - - public int send( Msg msg, MsgContext ep) - throws IOException - { - return super.nativeDispatch( msg, ep, CH_WRITE, 0 ); - } - - public int receive( Msg msg, MsgContext ep ) - throws IOException - { - int rc=super.nativeDispatch( msg, ep, CH_READ, 1 ); - - if( rc!=0 ) { - log.error("receive error: " + rc, new Throwable()); - return -1; - } - - msg.processHeader(); - - if (log.isDebugEnabled()) - log.debug("receive: total read = " + msg.getLen()); - - return msg.getLen(); - } - - public int flush( Msg msg, MsgContext ep) throws IOException { - return OK; - } - - public boolean isSameAddress( MsgContext ep ) { - return false; // Not supporting shutdown on this channel. - } - - boolean running=true; - - /** Accept incoming connections, dispatch to the thread pool - */ - void acceptConnections() { - if( apr==null ) return; - - if( log.isDebugEnabled() ) - log.debug("Accepting ajp connections on " + file); - - while( running ) { - try { - MsgContext ep=this.createMsgContext(); - - // blocking - opening a server connection. - int status=this.open(ep); - if( status != 0 && status != 2 ) { - log.error( "Error acceptin connection on " + file ); - break; - } - - // if( log.isDebugEnabled() ) - // log.debug("Accepted ajp connections "); - - AprConnection ajpConn= new AprConnection(this, ep); - tp.runIt( ajpConn ); - } catch( Exception ex ) { - ex.printStackTrace(); - } - } - } - - /** Process a single ajp connection. - */ - void processConnection(MsgContext ep) { - if( log.isDebugEnabled() ) - log.debug( "New ajp connection "); - try { - MsgAjp recv=new MsgAjp(); - while( running ) { - int res=this.receive( recv, ep ); - if( res<0 ) { - // EOS - break; - } - ep.setType(0); - log.debug( "Process msg "); - next.invoke( recv, ep ); - } - if( log.isDebugEnabled() ) - log.debug( "Closing un channel"); - try{ - Request req = ep.getRequest(); - if( req != null ) { - ObjectName roname = (ObjectName)ep.getNote(JMXRequestNote); - if( roname != null ) { - Registry.getRegistry(null, null).unregisterComponent(roname); - } - req.getRequestProcessor().setGlobalProcessor(null); - } - } catch( Exception ee) { - log.error( "Error, releasing connection",ee); - } - this.close( ep ); - } catch( Exception ex ) { - ex.printStackTrace(); - } - } - - public int invoke( Msg msg, MsgContext ep ) throws IOException { - int type=ep.getType(); - - switch( type ) { - case JkHandler.HANDLE_RECEIVE_PACKET: - return receive( msg, ep ); - case JkHandler.HANDLE_SEND_PACKET: - return send( msg, ep ); - case JkHandler.HANDLE_FLUSH: - return flush( msg, ep ); - } - - // return next.invoke( msg, ep ); - return OK; - } - - public String getChannelName() { - String encodedAddr = ""; - String address = file; - if (address != null) { - encodedAddr = "" + address; - if (encodedAddr.startsWith("/")) - encodedAddr = encodedAddr.substring(1); - encodedAddr = URLEncoder.encode(encodedAddr) ; - } - return ("jk-" + encodedAddr); - } - - private static org.apache.juli.logging.Log log= - org.apache.juli.logging.LogFactory.getLog( ChannelUn.class ); -} - -class AprAcceptor implements ThreadPoolRunnable { - ChannelUn wajp; - - AprAcceptor(ChannelUn wajp ) { - this.wajp=wajp; - } - - public Object[] getInitData() { - return null; - } - - public void runIt(Object thD[]) { - wajp.acceptConnections(); - } -} - -class AprConnection implements ThreadPoolRunnable { - ChannelUn wajp; - MsgContext ep; - - AprConnection(ChannelUn wajp, MsgContext ep) { - this.wajp=wajp; - this.ep=ep; - } - - - public Object[] getInitData() { - return null; - } - - public void runIt(Object perTh[]) { - wajp.processConnection(ep); - } -} diff --git a/java/org/apache/jk/common/JniHandler.java b/java/org/apache/jk/common/JniHandler.java deleted file mode 100644 index 8d9d76694..000000000 --- a/java/org/apache/jk/common/JniHandler.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * 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.common; - -import java.io.IOException; - -import javax.management.ObjectName; - -import org.apache.jk.apr.AprImpl; -import org.apache.jk.core.JkHandler; -import org.apache.jk.core.Msg; -import org.apache.jk.core.MsgContext; -import org.apache.jk.core.JkChannel; -import org.apache.tomcat.util.buf.ByteChunk; -import org.apache.tomcat.util.buf.C2BConverter; -import org.apache.tomcat.util.buf.MessageBytes; -import org.apache.tomcat.util.modeler.Registry; - - -/** - * Base class for components using native code ( libjkjni.so ). - * It allows to access the jk_env and wrap ( 'box' ? ) a native - * jk component, and call it's methods. - * - * Note that get/setAttribute are expensive ( Strings, etc ), - * invoke() is were all optimizations are done. We do recycle - * all memory on both C and java sides ( the only exception is - * when we attempt pinning but the VM doesn't support it ). The - * low level optimizations from ByteBuffer, etc are used to - * reduce the overhead of passing strings. - * - * @author Costin Manolache - */ -public class JniHandler extends JkHandler { - protected AprImpl apr; - - // The native side handler - protected long nativeJkHandlerP; - - protected String jkHome; - - // Dispatch table codes. Hardcoded for now, will change when we have more handlers. - public static final int JK_HANDLE_JNI_DISPATCH=0x15; - public static final int JK_HANDLE_SHM_DISPATCH=0x16; - - - public static final int MSG_NOTE=0; - public static final int MB_NOTE=2; - private boolean paused = false; - - - public JniHandler() { - } - - /** - */ - public void setJkHome( String s ) { - jkHome=s; - } - - public String getJkHome() { - return jkHome; - } - - /** You must call initNative() inside the component init() - */ - public void init() throws IOException { - // static field init, temp - } - - protected void initNative(String nativeComponentName) { - apr=(AprImpl)wEnv.getHandler("apr"); - if( apr==null ) { - // In most cases we can just load it automatically. - // that requires all libs to be installed in standard places - // ( LD_LIBRARY_PATH, /usr/lib - try { - apr=new AprImpl(); - wEnv.addHandler("apr", apr); - apr.init(); - if( oname != null ) { - ObjectName aprname=new ObjectName(oname.getDomain() + - ":type=JkHandler, name=apr"); - Registry.getRegistry(null, null).registerComponent(apr, aprname, null); - } - } catch( Throwable t ) { - log.debug("Can't load apr", t); - apr=null; - } - } - if( apr==null || ! apr.isLoaded() ) { - if( log.isDebugEnabled() ) - log.debug("No apr, disabling jni proxy "); - apr=null; - return; - } - - try { - long xEnv=apr.getJkEnv(); - nativeJkHandlerP=apr.getJkHandler(xEnv, nativeComponentName ); - - if( nativeJkHandlerP==0 ) { - log.debug("Component not found, creating it " + nativeComponentName ); - nativeJkHandlerP=apr.createJkHandler(xEnv, nativeComponentName); - } - log.debug("Native proxy " + nativeJkHandlerP ); - apr.releaseJkEnv(xEnv); - } catch( Throwable t ) { - apr=null; - log.info("Error calling apr ", t); - } - } - - public void appendString( Msg msg, String s, C2BConverter charsetDecoder) - throws IOException - { - ByteChunk bc=charsetDecoder.getByteChunk(); - charsetDecoder.recycle(); - charsetDecoder.convert( s ); - charsetDecoder.flushBuffer(); - msg.appendByteChunk( bc ); - } - - public void pause() throws Exception { - synchronized(this) { - paused = true; - } - } - - public void resume() throws Exception { - synchronized(this) { - paused = false; - notifyAll(); - } - } - - - /** Create a msg context to be used with the shm channel - */ - public MsgContext createMsgContext() { - if( nativeJkHandlerP==0 || apr==null ) - return null; - - synchronized(this) { - try{ - while(paused) { - wait(); - } - }catch(InterruptedException ie) { - // Ignore, since it can't happen - } - } - - try { - MsgContext msgCtx=new MsgContext(); - MsgAjp msg=new MsgAjp(); - - msgCtx.setSource( (JkChannel)this ); - msgCtx.setWorkerEnv( wEnv ); - - msgCtx.setNext( this ); - - msgCtx.setMsg( MSG_NOTE, msg); // XXX Use noteId - - C2BConverter c2b=new C2BConverter( "iso-8859-1" ); - msgCtx.setConverter( c2b ); - - MessageBytes tmpMB= MessageBytes.newInstance(); - msgCtx.setNote( MB_NOTE, tmpMB ); - return msgCtx; - } catch( Exception ex ) { - log.error("Can't create endpoint", ex); - return null; - } - } - - public void setNativeAttribute(String name, String val) throws IOException { - if( apr==null ) return; - - if( nativeJkHandlerP == 0 ) { - log.error( "Unitialized component " + name+ " " + val ); - return; - } - - long xEnv=apr.getJkEnv(); - - apr.jkSetAttribute( xEnv, nativeJkHandlerP, name, val ); - - apr.releaseJkEnv( xEnv ); - } - - public void initJkComponent() throws IOException { - if( apr==null ) return; - - if( nativeJkHandlerP == 0 ) { - log.error( "Unitialized component " ); - return; - } - - long xEnv=apr.getJkEnv(); - - apr.jkInit( xEnv, nativeJkHandlerP ); - - apr.releaseJkEnv( xEnv ); - } - - public void destroyJkComponent() throws IOException { - if( apr==null ) return; - - if( nativeJkHandlerP == 0 ) { - log.error( "Unitialized component " ); - return; - } - - long xEnv=apr.getJkEnv(); - - apr.jkDestroy( xEnv, nativeJkHandlerP ); - - apr.releaseJkEnv( xEnv ); - } - - - - protected void setNativeEndpoint(MsgContext msgCtx) { - long xEnv=apr.getJkEnv(); - msgCtx.setJniEnv( xEnv ); - - long epP=apr.createJkHandler(xEnv, "endpoint"); - log.debug("create ep " + epP ); - if( epP == 0 ) return; - apr.jkInit( xEnv, epP ); - msgCtx.setJniContext( epP ); - - } - - protected void recycleNative(MsgContext ep) { - apr.jkRecycle(ep.getJniEnv(), ep.getJniContext()); - } - - /** send and get the response in the same buffer. This calls the - * method on the wrapped jk_bean object. - */ - protected int nativeDispatch( Msg msg, MsgContext ep, int code, int raw ) - throws IOException - { - if( log.isDebugEnabled() ) - log.debug( "Sending packet " + code + " " + raw); - - if( raw == 0 ) { - msg.end(); - - if( log.isTraceEnabled() ) msg.dump("OUT:" ); - } - - // Create ( or reuse ) the jk_endpoint ( the native pair of - // MsgContext ) - long xEnv=ep.getJniEnv(); - long nativeContext=ep.getJniContext(); - if( nativeContext==0 || xEnv==0 ) { - setNativeEndpoint( ep ); - xEnv=ep.getJniEnv(); - nativeContext=ep.getJniContext(); - } - - if( xEnv==0 || nativeContext==0 || nativeJkHandlerP==0 ) { - log.error("invokeNative: Null pointer "); - return -1; - } - - // Will process the message in the current thread. - // No wait needed to receive the response, if any - int status=AprImpl.jkInvoke( xEnv, - nativeJkHandlerP, - nativeContext, - code, msg.getBuffer(), 0, msg.getLen(), raw ); - - if( status != 0 && status != 2 ) { - log.error( "nativeDispatch: error " + status, new Throwable() ); - } - - if( log.isDebugEnabled() ) log.debug( "Sending packet - done " + status); - return status; - } - - /** Base implementation for invoke. Dispatch the action to the native - * code, where invoke() is called on the wrapped jk_bean. - */ - public int invoke(Msg msg, MsgContext ep ) - throws IOException - { - long xEnv=ep.getJniEnv(); - int type=ep.getType(); - - int status=nativeDispatch(msg, ep, type, 0 ); - - apr.jkRecycle(xEnv, ep.getJniContext()); - apr.releaseJkEnv( xEnv ); - return status; - } - - private static org.apache.juli.logging.Log log= - org.apache.juli.logging.LogFactory.getLog( JniHandler.class ); -} diff --git a/java/org/apache/jk/common/Shm.java b/java/org/apache/jk/common/Shm.java deleted file mode 100644 index c4360678e..000000000 --- a/java/org/apache/jk/common/Shm.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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.common; - -import java.io.IOException; -import java.util.Vector; - -import org.apache.jk.apr.AprImpl; -import org.apache.jk.core.Msg; -import org.apache.jk.core.MsgContext; -import org.apache.jk.core.WorkerEnv; -import org.apache.tomcat.util.IntrospectionUtils; -import org.apache.tomcat.util.buf.C2BConverter; - -/* The code is a bit confusing at this moment - the class is used as - a Bean, or ant Task, or CLI - i.e. you set properties and call execute. - - That's different from the rest of jk handlers wich are stateless ( but - similar with Coyote-http ). -*/ - - -/** Handle the shared memory objects. - * - * @author Costin Manolache - */ -public class Shm extends JniHandler { - String file="/tmp/shm.file"; - int size; - String host="localhost"; - int port=8009; - String unixSocket; - - boolean help=false; - boolean unregister=false; - boolean reset=false; - String dumpFile=null; - - Vector groups = new Vector(); - - // Will be dynamic ( getMethodId() ) after things are stable - static final int SHM_WRITE_SLOT=2; - static final int SHM_RESET=5; - static final int SHM_DUMP=6; - - public Shm() { - } - - /** Scoreboard location - */ - public void setFile( String f ) { - file=f; - } - - /** Copy the scoreboard in a file for debugging - * Will also log a lot of information about what's in the scoreboard. - */ - public void setDump( String dumpFile ) { - this.dumpFile=dumpFile; - } - - /** Size. Used only if the scoreboard is to be created. - */ - public void setSize( int size ) { - this.size=size; - } - - /** Set this to get the scoreboard reset. - * The shm segment will be destroyed and a new one created, - * with the provided size. - * - * Requires "file" and "size". - */ - public void setReset(boolean b) { - reset=true; - } - - /** Ajp13 host - */ - public void setHost( String host ) { - this.host=host; - } - - /** Mark this instance as belonging to a group - */ - public void setGroup( String grp ) { - groups.addElement( grp ); - } - - /** Ajp13 port - */ - public void setPort( int port ) { - this.port=port; - } - - /** Unix socket where tomcat is listening. - * Use it only if tomcat is on the same host, of course - */ - public void setUnixSocket( String unixSocket ) { - this.unixSocket=unixSocket; - } - - /** Set this option to mark the tomcat instance as - 'down', so apache will no longer forward messages to it. - Note that requests with a session will still try this - host first. - - This can be used to implement gracefull shutdown. - - Host and port are still required, since they are used - to identify tomcat. - */ - public void setUnregister( boolean unregister ) { - this.unregister=true; - } - - public void init() throws IOException { - super.initNative( "shm" ); - if( apr==null ) return; - if( file==null ) { - log.error("No shm file, disabling shared memory"); - apr=null; - return; - } - - // Set properties and call init. - setNativeAttribute( "file", file ); - if( size > 0 ) - setNativeAttribute( "size", Integer.toString( size ) ); - - initJkComponent(); - } - - public void resetScoreboard() throws IOException { - if( apr==null ) return; - MsgContext mCtx=createMsgContext(); - Msg msg=mCtx.getMsg(0); - msg.reset(); - - msg.appendByte( SHM_RESET ); - - this.invoke( msg, mCtx ); - } - - public void dumpScoreboard(String fname) throws IOException { - if( apr==null ) return; - MsgContext mCtx=createMsgContext(); - Msg msg=mCtx.getMsg(0); - C2BConverter c2b=mCtx.getConverter(); - msg.reset(); - - msg.appendByte( SHM_DUMP ); - - appendString( msg, fname, c2b); - - this.invoke( msg, mCtx ); - } - - /** Register a tomcat instance - * XXX make it more flexible - */ - public void registerTomcat(String host, int port, String unixDomain) - throws IOException - { - String instanceId=host+":" + port; - - String slotName="TOMCAT:" + instanceId; - MsgContext mCtx=createMsgContext(); - Msg msg=mCtx.getMsg(0); - msg.reset(); - C2BConverter c2b=mCtx.getConverter(); - - msg.appendByte( SHM_WRITE_SLOT ); - appendString( msg, slotName, c2b ); - - int channelCnt=1; - if( unixDomain != null ) channelCnt++; - - // number of groups. 0 means the default lb. - msg.appendInt( groups.size() ); - for( int i=0; i