init
This commit is contained in:
84
java/org/apache/catalina/tribes/io/BufferPool.java
Normal file
84
java/org/apache/catalina/tribes/io/BufferPool.java
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BufferPool {
|
||||
private static final Log log = LogFactory.getLog(BufferPool.class);
|
||||
|
||||
public static final int DEFAULT_POOL_SIZE = 100*1024*1024; //100MB
|
||||
|
||||
protected static final StringManager sm = StringManager.getManager(BufferPool.class);
|
||||
|
||||
|
||||
|
||||
protected static volatile BufferPool instance = null;
|
||||
protected final BufferPoolAPI pool;
|
||||
|
||||
private BufferPool(BufferPoolAPI pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public XByteBuffer getBuffer(int minSize, boolean discard) {
|
||||
if ( pool != null ) return pool.getBuffer(minSize, discard);
|
||||
else return new XByteBuffer(minSize,discard);
|
||||
}
|
||||
|
||||
public void returnBuffer(XByteBuffer buffer) {
|
||||
if ( pool != null ) pool.returnBuffer(buffer);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if ( pool != null ) pool.clear();
|
||||
}
|
||||
|
||||
|
||||
public static BufferPool getBufferPool() {
|
||||
if (instance == null) {
|
||||
synchronized (BufferPool.class) {
|
||||
if (instance == null) {
|
||||
BufferPoolAPI pool = new BufferPool15Impl();
|
||||
pool.setMaxSize(DEFAULT_POOL_SIZE);
|
||||
log.info(sm.getString("bufferPool.created",
|
||||
Integer.toString(DEFAULT_POOL_SIZE), pool.getClass().getName()));
|
||||
instance = new BufferPool(pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public static interface BufferPoolAPI {
|
||||
public void setMaxSize(int bytes);
|
||||
|
||||
public XByteBuffer getBuffer(int minSize, boolean discard);
|
||||
|
||||
public void returnBuffer(XByteBuffer buffer);
|
||||
|
||||
public void clear();
|
||||
}
|
||||
}
|
||||
67
java/org/apache/catalina/tribes/io/BufferPool15Impl.java
Normal file
67
java/org/apache/catalina/tribes/io/BufferPool15Impl.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
class BufferPool15Impl implements BufferPool.BufferPoolAPI {
|
||||
protected int maxSize;
|
||||
protected final AtomicInteger size = new AtomicInteger(0);
|
||||
protected final ConcurrentLinkedQueue<XByteBuffer> queue =
|
||||
new ConcurrentLinkedQueue<>();
|
||||
|
||||
@Override
|
||||
public void setMaxSize(int bytes) {
|
||||
this.maxSize = bytes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public XByteBuffer getBuffer(int minSize, boolean discard) {
|
||||
XByteBuffer buffer = queue.poll();
|
||||
if ( buffer != null ) size.addAndGet(-buffer.getCapacity());
|
||||
if ( buffer == null ) buffer = new XByteBuffer(minSize,discard);
|
||||
else if ( buffer.getCapacity() <= minSize ) buffer.expand(minSize);
|
||||
buffer.setDiscard(discard);
|
||||
buffer.reset();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnBuffer(XByteBuffer buffer) {
|
||||
if ( (size.get() + buffer.getCapacity()) <= maxSize ) {
|
||||
size.addAndGet(buffer.getCapacity());
|
||||
queue.offer(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
queue.clear();
|
||||
size.set(0);
|
||||
}
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
}
|
||||
374
java/org/apache/catalina/tribes/io/ChannelData.java
Normal file
374
java/org/apache/catalina/tribes/io/ChannelData.java
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.catalina.tribes.Channel;
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.Member;
|
||||
import org.apache.catalina.tribes.membership.MemberImpl;
|
||||
import org.apache.catalina.tribes.util.UUIDGenerator;
|
||||
|
||||
/**
|
||||
* The <code>ChannelData</code> object is used to transfer a message through the
|
||||
* channel interceptor stack and eventually out on a transport to be sent
|
||||
* to another node. While the message is being processed by the different
|
||||
* interceptors, the message data can be manipulated as each interceptor seems appropriate.
|
||||
* @author Peter Rossbach
|
||||
*/
|
||||
public class ChannelData implements ChannelMessage {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final ChannelData[] EMPTY_DATA_ARRAY = new ChannelData[0];
|
||||
|
||||
public static volatile boolean USE_SECURE_RANDOM_FOR_UUID = false;
|
||||
|
||||
/**
|
||||
* The options this message was sent with
|
||||
*/
|
||||
private int options = 0 ;
|
||||
/**
|
||||
* The message data, stored in a dynamic buffer
|
||||
*/
|
||||
private XByteBuffer message ;
|
||||
/**
|
||||
* The timestamp that goes with this message
|
||||
*/
|
||||
private long timestamp ;
|
||||
/**
|
||||
* A unique message id
|
||||
*/
|
||||
private byte[] uniqueId ;
|
||||
/**
|
||||
* The source or reply-to address for this message
|
||||
*/
|
||||
private Member address;
|
||||
|
||||
/**
|
||||
* Creates an empty channel data with a new unique Id
|
||||
* @see #ChannelData(boolean)
|
||||
*/
|
||||
public ChannelData() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty channel data object
|
||||
* @param generateUUID boolean - if true, a unique Id will be generated
|
||||
*/
|
||||
public ChannelData(boolean generateUUID) {
|
||||
if ( generateUUID ) generateUUID();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new channel data object with data
|
||||
* @param uniqueId - unique message id
|
||||
* @param message - message data
|
||||
* @param timestamp - message timestamp
|
||||
*/
|
||||
public ChannelData(byte[] uniqueId, XByteBuffer message, long timestamp) {
|
||||
this.uniqueId = uniqueId;
|
||||
this.message = message;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the message byte buffer
|
||||
*/
|
||||
@Override
|
||||
public XByteBuffer getMessage() {
|
||||
return message;
|
||||
}
|
||||
/**
|
||||
* @param message The message to send.
|
||||
*/
|
||||
@Override
|
||||
public void setMessage(XByteBuffer message) {
|
||||
this.message = message;
|
||||
}
|
||||
/**
|
||||
* @return Returns the timestamp.
|
||||
*/
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
/**
|
||||
* @param timestamp The timestamp to send
|
||||
*/
|
||||
@Override
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
/**
|
||||
* @return Returns the uniqueId.
|
||||
*/
|
||||
@Override
|
||||
public byte[] getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
/**
|
||||
* @param uniqueId The uniqueId to send.
|
||||
*/
|
||||
public void setUniqueId(byte[] uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
/**
|
||||
* @return returns the message options
|
||||
* see org.apache.catalina.tribes.Channel#sendMessage(org.apache.catalina.tribes.Member[], java.io.Serializable, int)
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public int getOptions() {
|
||||
return options;
|
||||
}
|
||||
/**
|
||||
* Sets the message options.
|
||||
*
|
||||
* @param options the message options
|
||||
*/
|
||||
@Override
|
||||
public void setOptions(int options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source or reply-to address
|
||||
* @return Member
|
||||
*/
|
||||
@Override
|
||||
public Member getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source or reply-to address
|
||||
* @param address Member
|
||||
*/
|
||||
@Override
|
||||
public void setAddress(Member address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID and invokes setUniqueId
|
||||
*/
|
||||
public void generateUUID() {
|
||||
byte[] data = new byte[16];
|
||||
UUIDGenerator.randomUUID(USE_SECURE_RANDOM_FOR_UUID,data,0);
|
||||
setUniqueId(data);
|
||||
}
|
||||
|
||||
public int getDataPackageLength() {
|
||||
int length =
|
||||
4 + //options
|
||||
8 + //timestamp off=4
|
||||
4 + //unique id length off=12
|
||||
uniqueId.length+ //id data off=12+uniqueId.length
|
||||
4 + //addr length off=12+uniqueId.length+4
|
||||
address.getDataLength()+ //member data off=12+uniqueId.length+4+add.length
|
||||
4 + //message length off=12+uniqueId.length+4+add.length+4
|
||||
message.getLength();
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the ChannelData object into a byte[] array
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getDataPackage() {
|
||||
int length = getDataPackageLength();
|
||||
byte[] data = new byte[length];
|
||||
int offset = 0;
|
||||
return getDataPackage(data,offset);
|
||||
}
|
||||
|
||||
public byte[] getDataPackage(byte[] data, int offset) {
|
||||
byte[] addr = address.getData(false);
|
||||
XByteBuffer.toBytes(options,data,offset);
|
||||
offset += 4; //options
|
||||
XByteBuffer.toBytes(timestamp,data,offset);
|
||||
offset += 8; //timestamp
|
||||
XByteBuffer.toBytes(uniqueId.length,data,offset);
|
||||
offset += 4; //uniqueId.length
|
||||
System.arraycopy(uniqueId,0,data,offset,uniqueId.length);
|
||||
offset += uniqueId.length; //uniqueId data
|
||||
XByteBuffer.toBytes(addr.length,data,offset);
|
||||
offset += 4; //addr.length
|
||||
System.arraycopy(addr,0,data,offset,addr.length);
|
||||
offset += addr.length; //addr data
|
||||
XByteBuffer.toBytes(message.getLength(),data,offset);
|
||||
offset += 4; //message.length
|
||||
System.arraycopy(message.getBytesDirect(),0,data,offset,message.getLength());
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a ChannelData object from a byte array
|
||||
* @param xbuf byte[]
|
||||
* @return ChannelData
|
||||
*/
|
||||
public static ChannelData getDataFromPackage(XByteBuffer xbuf) {
|
||||
ChannelData data = new ChannelData(false);
|
||||
int offset = 0;
|
||||
data.setOptions(XByteBuffer.toInt(xbuf.getBytesDirect(),offset));
|
||||
offset += 4; //options
|
||||
data.setTimestamp(XByteBuffer.toLong(xbuf.getBytesDirect(),offset));
|
||||
offset += 8; //timestamp
|
||||
data.uniqueId = new byte[XByteBuffer.toInt(xbuf.getBytesDirect(),offset)];
|
||||
offset += 4; //uniqueId length
|
||||
System.arraycopy(xbuf.getBytesDirect(),offset,data.uniqueId,0,data.uniqueId.length);
|
||||
offset += data.uniqueId.length; //uniqueId data
|
||||
//byte[] addr = new byte[XByteBuffer.toInt(xbuf.getBytesDirect(),offset)];
|
||||
int addrlen = XByteBuffer.toInt(xbuf.getBytesDirect(),offset);
|
||||
offset += 4; //addr length
|
||||
//System.arraycopy(xbuf.getBytesDirect(),offset,addr,0,addr.length);
|
||||
data.setAddress(MemberImpl.getMember(xbuf.getBytesDirect(),offset,addrlen));
|
||||
//offset += addr.length; //addr data
|
||||
offset += addrlen;
|
||||
int xsize = XByteBuffer.toInt(xbuf.getBytesDirect(),offset);
|
||||
offset += 4; //xsize length
|
||||
System.arraycopy(xbuf.getBytesDirect(),offset,xbuf.getBytesDirect(),0,xsize);
|
||||
xbuf.setLength(xsize);
|
||||
data.message = xbuf;
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
public static ChannelData getDataFromPackage(byte[] b) {
|
||||
ChannelData data = new ChannelData(false);
|
||||
int offset = 0;
|
||||
data.setOptions(XByteBuffer.toInt(b,offset));
|
||||
offset += 4; //options
|
||||
data.setTimestamp(XByteBuffer.toLong(b,offset));
|
||||
offset += 8; //timestamp
|
||||
data.uniqueId = new byte[XByteBuffer.toInt(b,offset)];
|
||||
offset += 4; //uniqueId length
|
||||
System.arraycopy(b,offset,data.uniqueId,0,data.uniqueId.length);
|
||||
offset += data.uniqueId.length; //uniqueId data
|
||||
byte[] addr = new byte[XByteBuffer.toInt(b,offset)];
|
||||
offset += 4; //addr length
|
||||
System.arraycopy(b,offset,addr,0,addr.length);
|
||||
data.setAddress(MemberImpl.getMember(addr));
|
||||
offset += addr.length; //addr data
|
||||
int xsize = XByteBuffer.toInt(b,offset);
|
||||
//data.message = new XByteBuffer(new byte[xsize],false);
|
||||
data.message = BufferPool.getBufferPool().getBuffer(xsize,false);
|
||||
offset += 4; //message length
|
||||
System.arraycopy(b,offset,data.message.getBytesDirect(),0,xsize);
|
||||
data.message.append(b,offset,xsize);
|
||||
offset += xsize; //message data
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return XByteBuffer.toInt(getUniqueId(),0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares to ChannelData objects, only compares on getUniqueId().equals(o.getUniqueId())
|
||||
* @param o Object
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( o instanceof ChannelData ) {
|
||||
return Arrays.equals(getUniqueId(),((ChannelData)o).getUniqueId());
|
||||
} else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow clone, only the data gets recreated
|
||||
* @return ClusterData
|
||||
*/
|
||||
@Override
|
||||
public ChannelData clone() {
|
||||
ChannelData clone;
|
||||
try {
|
||||
clone = (ChannelData) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// Cannot happen
|
||||
throw new AssertionError();
|
||||
}
|
||||
if (this.message != null) {
|
||||
clone.message = new XByteBuffer(this.message.getBytesDirect(),false);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete clone
|
||||
* @return ClusterData
|
||||
*/
|
||||
@Override
|
||||
public Object deepclone() {
|
||||
byte[] d = this.getDataPackage();
|
||||
return ChannelData.getDataFromPackage(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method, returns true if the options flag indicates that an ack
|
||||
* is to be sent after the message has been received and processed
|
||||
* @param options int - the options for the message
|
||||
* @return boolean
|
||||
* @see org.apache.catalina.tribes.Channel#SEND_OPTIONS_USE_ACK
|
||||
* @see org.apache.catalina.tribes.Channel#SEND_OPTIONS_SYNCHRONIZED_ACK
|
||||
*/
|
||||
public static boolean sendAckSync(int options) {
|
||||
return ( (Channel.SEND_OPTIONS_USE_ACK & options) == Channel.SEND_OPTIONS_USE_ACK) &&
|
||||
( (Channel.SEND_OPTIONS_SYNCHRONIZED_ACK & options) == Channel.SEND_OPTIONS_SYNCHRONIZED_ACK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Utility method, returns true if the options flag indicates that an ack
|
||||
* is to be sent after the message has been received but not yet processed
|
||||
* @param options int - the options for the message
|
||||
* @return boolean
|
||||
* @see org.apache.catalina.tribes.Channel#SEND_OPTIONS_USE_ACK
|
||||
* @see org.apache.catalina.tribes.Channel#SEND_OPTIONS_SYNCHRONIZED_ACK
|
||||
*/
|
||||
public static boolean sendAckAsync(int options) {
|
||||
return ( (Channel.SEND_OPTIONS_USE_ACK & options) == Channel.SEND_OPTIONS_USE_ACK) &&
|
||||
( (Channel.SEND_OPTIONS_SYNCHRONIZED_ACK & options) != Channel.SEND_OPTIONS_SYNCHRONIZED_ACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("ClusterData[src=");
|
||||
buf.append(getAddress()).append("; id=");
|
||||
buf.append(bToS(getUniqueId())).append("; sent=");
|
||||
buf.append(new Timestamp(this.getTimestamp()).toString()).append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String bToS(byte[] data) {
|
||||
StringBuilder buf = new StringBuilder(4*16);
|
||||
buf.append("{");
|
||||
for (int i=0; data!=null && i<data.length; i++ ) buf.append(String.valueOf(data[i])).append(" ");
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Byte array output stream that exposes the byte array directly
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DirectByteArrayOutputStream extends OutputStream {
|
||||
|
||||
private final XByteBuffer buffer;
|
||||
|
||||
public DirectByteArrayOutputStream(int size) {
|
||||
buffer = new XByteBuffer(size,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this output stream.
|
||||
*
|
||||
* @param b the <code>byte</code>.
|
||||
* @throws IOException if an I/O error occurs. In particular, an
|
||||
* <code>IOException</code> may be thrown if the output stream has
|
||||
* been closed.
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
buffer.append((byte)b);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return buffer.getLength();
|
||||
}
|
||||
|
||||
public byte[] getArrayDirect() {
|
||||
return buffer.getBytesDirect();
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
return buffer.getBytes();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
40
java/org/apache/catalina/tribes/io/ListenCallback.java
Normal file
40
java/org/apache/catalina/tribes/io/ListenCallback.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal interface, similar to the MessageListener but used
|
||||
* at the IO base
|
||||
* The listen callback interface is used by the replication system
|
||||
* when data has been received. The interface does not care about
|
||||
* objects and marshalling and just passes the bytes straight through.
|
||||
*/
|
||||
public interface ListenCallback
|
||||
{
|
||||
/**
|
||||
* This method is invoked on the callback object to notify it that new data has
|
||||
* been received from one of the cluster nodes.
|
||||
* @param data - the message bytes received from the cluster/replication system
|
||||
*/
|
||||
public void messageDataReceived(ChannelMessage data);
|
||||
|
||||
}
|
||||
27
java/org/apache/catalina/tribes/io/LocalStrings.properties
Normal file
27
java/org/apache/catalina/tribes/io/LocalStrings.properties
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
bufferPool.created=Created a buffer pool with max size:[{0}] bytes of type: [{1}]
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=Unable to retrieve the socket receiver buffer size, setting to default 43800 bytes.
|
||||
|
||||
replicationStream.conflict=conflicting non-public interface class loaders
|
||||
|
||||
xByteBuffer.discarded.invalidHeader=Discarded the package, invalid header
|
||||
xByteBuffer.no.package=No package exists in XByteBuffer
|
||||
xByteBuffer.size.larger.buffer=Size is larger than existing buffer.
|
||||
xByteBuffer.unableCreate=Unable to create data package, buffer is too small.
|
||||
xByteBuffer.unableTrim=Cannot trim more bytes than are available. length:[{0}] trim:[{1}]
|
||||
xByteBuffer.wrong.class=Message has the wrong class. It should implement Serializable, instead it is:[{0}]
|
||||
@@ -0,0 +1,20 @@
|
||||
# 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.
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=Kann die Größe der Socket Puffer nicht auslesen. Setze sie auf den Standardwert von 43800 Bytes.
|
||||
|
||||
xByteBuffer.no.package=In XByteBuffer existiert kein Paket
|
||||
xByteBuffer.unableCreate=Kann Daten Paket nicht erzeugen, da der Puffer zu klein ist
|
||||
xByteBuffer.wrong.class=Nachricht hat eine falsche Klasse. Sie sollte Serializable implementieren, sie implementiert aber: [{0}]
|
||||
@@ -0,0 +1,23 @@
|
||||
# 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.
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=Incapáz de recuperar el tamaño del buffer receptor, fijando el valor por defecto a 43800 bytes.\n
|
||||
|
||||
replicationStream.conflict=hay conflicto en la clase de los cargadores de la interfaz no pública
|
||||
|
||||
xByteBuffer.no.package=No existe paquete en XByteBuffer
|
||||
xByteBuffer.size.larger.buffer=El tamaño es mayor que el buffer
|
||||
xByteBuffer.unableCreate=Imposible crear el paquete de datos, el buffer es demasiado pequeño.
|
||||
xByteBuffer.wrong.class=El mensaje tiene la clase errónea. Debe implementar Serializable, pero en su lugar es:[{0}]
|
||||
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
bufferPool.created=Création d''un pool de tampons de taille maximale: [{0}] octets de type: [{1}]
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=Incapacité de récupérer la taille du tampon du socket de réception, forcé à 43800 octets
|
||||
|
||||
replicationStream.conflict=Conflit entre des interfaces non-publics ayant des chargeurs de classe différents
|
||||
|
||||
xByteBuffer.discarded.invalidHeader=L'en-tête est invalide donc le paquet a été abandonné
|
||||
xByteBuffer.no.package=Il n'y a aucun package dans XByteBuffer
|
||||
xByteBuffer.size.larger.buffer=La taille est plus grande que celle du buffer existant
|
||||
xByteBuffer.unableCreate=Impossible de créer le package data, le tampon de mémoire est trop petit
|
||||
xByteBuffer.unableTrim=Impossible d''élaguer plus d''octets que ce qui est disponible, longueur: [{0}] élagage: [{1}]
|
||||
xByteBuffer.wrong.class=Message n''a pas la bonne classe. Cela doit implémenter Serializable au lieu de [{0}]
|
||||
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
bufferPool.created=最大サイズ[{1}]のタイプの[{0}]バイトのバッファプールを作成しました。
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=TCP ソケットのレシーバーバッファサイズを取得できなかったため初期値として 43800 byte を設定します。
|
||||
|
||||
replicationStream.conflict=public でないインターフェイスのクラスローダーが複数存在します。
|
||||
|
||||
xByteBuffer.discarded.invalidHeader=ヘッダーが不正なためパッケージを破棄します。
|
||||
xByteBuffer.no.package=XByteBuffer にパッケージがありません。
|
||||
xByteBuffer.size.larger.buffer=バッファ長より大きな値がサイズとして指定されました。
|
||||
xByteBuffer.unableCreate=バッファーが小さすぎてデータパッケージを作成できません。
|
||||
xByteBuffer.unableTrim=利用可能なバイト数より多くのバイトをトリムすることはできません。 長さ:[{0}]トリム:[{1}]
|
||||
xByteBuffer.wrong.class=メッセージのClassが間違っています。 それはSerializableを実装するはずですが、代わりに[{0}]です。
|
||||
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
bufferPool.created=타입이 [{1}](이)고 최대 크기가 [{0}] 바이트를 사용하여 버퍼 풀을 생성했습니다.
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=소켓 receiver의 버퍼 크기를 알 수 없습니다. 기본 값인 43800 바이트로 설정합니다.
|
||||
|
||||
replicationStream.conflict=해당 클래스의 클래스로더와, 그 클래스의 특정 non-public 인터페이스의 클래스로더가 일치하지 않아 충돌합니다.
|
||||
|
||||
xByteBuffer.discarded.invalidHeader=유효하지 않은 헤더로 인해 패키지를 폐기했습니다.
|
||||
xByteBuffer.no.package=XByteBuffer에 어떤 패키지도 존재하지 않습니다.
|
||||
xByteBuffer.size.larger.buffer=크기가 기존 버퍼의 길이보다 큽니다.
|
||||
xByteBuffer.unableCreate=데이터 패키지를 생성할 수 없습니다. 버퍼가 너무 작습니다.
|
||||
xByteBuffer.unableTrim=가용한 버퍼 크기보다 더 많은 바이트들을 잘라낼 수는 없습니다. 버퍼 길이:[{0}], 잘라낼 길이:[{1}]
|
||||
xByteBuffer.wrong.class=메시지가 Serializable 인터페이스를 구현하지 않은 클래스입니다. 클래스는 [{0}]입니다.
|
||||
@@ -0,0 +1,16 @@
|
||||
# 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.
|
||||
|
||||
replicationStream.conflict=конфликтующие не-публичные загрузчики классов
|
||||
@@ -0,0 +1,23 @@
|
||||
# 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.
|
||||
|
||||
objectReader.retrieveFailed.socketReceiverBufferSize=无法检索套接字接收器缓冲区大小,设置为默认43800字节。
|
||||
|
||||
replicationStream.conflict=和非公开接口类加载器冲突
|
||||
|
||||
xByteBuffer.no.package=XByteBuffer中不存在数据包
|
||||
xByteBuffer.size.larger.buffer=大小比现有缓冲区大。
|
||||
xByteBuffer.unableCreate=不能创建数据包, buffer 太小
|
||||
xByteBuffer.wrong.class=消息对应类不符合要求。 它应该实现Serializable,而不是:[{0}]。
|
||||
167
java/org/apache/catalina/tribes/io/ObjectReader.java
Normal file
167
java/org/apache/catalina/tribes/io/ObjectReader.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
import org.apache.catalina.tribes.ChannelMessage;
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The object reader object is an object used in conjunction with
|
||||
* java.nio TCP messages. This object stores the message bytes in a
|
||||
* <code>XByteBuffer</code> until a full package has been received.
|
||||
* This object uses an XByteBuffer which is an extendable object buffer that also allows
|
||||
* for message encoding and decoding.
|
||||
*/
|
||||
public class ObjectReader {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ObjectReader.class);
|
||||
protected static final StringManager sm = StringManager.getManager(ObjectReader.class);
|
||||
|
||||
private XByteBuffer buffer;
|
||||
|
||||
protected long lastAccess = System.currentTimeMillis();
|
||||
|
||||
protected boolean accessed = false;
|
||||
private volatile boolean cancelled;
|
||||
|
||||
public ObjectReader(int packetSize) {
|
||||
this.buffer = new XByteBuffer(packetSize, true);
|
||||
}
|
||||
/**
|
||||
* Creates an <code>ObjectReader</code> for a TCP NIO socket channel
|
||||
* @param channel - the channel to be read.
|
||||
*/
|
||||
public ObjectReader(SocketChannel channel) {
|
||||
this(channel.socket());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an <code>ObjectReader</code> for a TCP socket
|
||||
* @param socket Socket
|
||||
*/
|
||||
public ObjectReader(Socket socket) {
|
||||
try{
|
||||
this.buffer = new XByteBuffer(socket.getReceiveBufferSize(), true);
|
||||
}catch ( IOException x ) {
|
||||
//unable to get buffer size
|
||||
log.warn(sm.getString("objectReader.retrieveFailed.socketReceiverBufferSize"));
|
||||
this.buffer = new XByteBuffer(43800,true);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void access() {
|
||||
this.accessed = true;
|
||||
this.lastAccess = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public synchronized void finish() {
|
||||
this.accessed = false;
|
||||
this.lastAccess = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public synchronized boolean isAccessed() {
|
||||
return this.accessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new bytes to buffer.
|
||||
* @see XByteBuffer#countPackages()
|
||||
* @param data new transfer buffer
|
||||
* @param len length in buffer
|
||||
* @param count whether to return the count
|
||||
* @return number of messages that was sent to callback (or -1 if count == false)
|
||||
*/
|
||||
public int append(ByteBuffer data, int len, boolean count) {
|
||||
buffer.append(data,len);
|
||||
int pkgCnt = -1;
|
||||
if ( count ) pkgCnt = buffer.countPackages();
|
||||
return pkgCnt;
|
||||
}
|
||||
|
||||
public int append(byte[] data,int off,int len, boolean count) {
|
||||
buffer.append(data,off,len);
|
||||
int pkgCnt = -1;
|
||||
if ( count ) pkgCnt = buffer.countPackages();
|
||||
return pkgCnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send buffer to cluster listener (callback).
|
||||
* Is message complete receiver send message to callback?
|
||||
*
|
||||
* @see org.apache.catalina.tribes.transport.ReceiverBase#messageDataReceived(ChannelMessage)
|
||||
* @see XByteBuffer#doesPackageExist()
|
||||
* @see XByteBuffer#extractPackage(boolean)
|
||||
*
|
||||
* @return number of received packages/messages
|
||||
*/
|
||||
public ChannelMessage[] execute() {
|
||||
int pkgCnt = buffer.countPackages();
|
||||
ChannelMessage[] result = new ChannelMessage[pkgCnt];
|
||||
for (int i=0; i<pkgCnt; i++) {
|
||||
ChannelMessage data = buffer.extractPackage(true);
|
||||
result[i] = data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int bufferSize() {
|
||||
return buffer.getLength();
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPackage() {
|
||||
return buffer.countPackages(true)>0;
|
||||
}
|
||||
/**
|
||||
* Returns the number of packages that the reader has read
|
||||
* @return int
|
||||
*/
|
||||
public int count() {
|
||||
return buffer.countPackages();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.buffer = null;
|
||||
}
|
||||
|
||||
public synchronized long getLastAccess() {
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public synchronized void setLastAccess(long lastAccess) {
|
||||
this.lastAccess = lastAccess;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
}
|
||||
170
java/org/apache/catalina/tribes/io/ReplicationStream.java
Normal file
170
java/org/apache/catalina/tribes/io/ReplicationStream.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.catalina.tribes.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.apache.catalina.tribes.util.StringManager;
|
||||
|
||||
/**
|
||||
* Custom subclass of <code>ObjectInputStream</code> that loads from the
|
||||
* class loader for this web application. This allows classes defined only
|
||||
* with the web application to be found correctly.
|
||||
*
|
||||
* @author Craig R. McClanahan
|
||||
* @author Bip Thelin
|
||||
*/
|
||||
public final class ReplicationStream extends ObjectInputStream {
|
||||
|
||||
static final StringManager sm = StringManager.getManager(ReplicationStream.class);
|
||||
|
||||
/**
|
||||
* The class loader we will use to resolve classes.
|
||||
*/
|
||||
private ClassLoader[] classLoaders = null;
|
||||
|
||||
/**
|
||||
* Construct a new instance of CustomObjectInputStream
|
||||
*
|
||||
* @param stream The input stream we will read from
|
||||
* @param classLoaders The class loader array used to instantiate objects
|
||||
*
|
||||
* @exception IOException if an input/output error occurs
|
||||
*/
|
||||
public ReplicationStream(InputStream stream,
|
||||
ClassLoader[] classLoaders)
|
||||
throws IOException {
|
||||
|
||||
super(stream);
|
||||
this.classLoaders = classLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the local class equivalent of the specified stream class
|
||||
* description, by using the class loader assigned to this Context.
|
||||
*
|
||||
* @param classDesc Class description from the input stream
|
||||
*
|
||||
* @exception ClassNotFoundException if this class cannot be found
|
||||
* @exception IOException if an input/output error occurs
|
||||
*/
|
||||
@Override
|
||||
public Class<?> resolveClass(ObjectStreamClass classDesc)
|
||||
throws ClassNotFoundException, IOException {
|
||||
String name = classDesc.getName();
|
||||
try {
|
||||
return resolveClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return super.resolveClass(classDesc);
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> resolveClass(String name) throws ClassNotFoundException {
|
||||
|
||||
boolean tryRepFirst = name.startsWith("org.apache.catalina.tribes");
|
||||
try {
|
||||
if (tryRepFirst)
|
||||
return findReplicationClass(name);
|
||||
else
|
||||
return findExternalClass(name);
|
||||
} catch (Exception x) {
|
||||
if (tryRepFirst)
|
||||
return findExternalClass(name);
|
||||
else
|
||||
return findReplicationClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ObjectInputStream.resolveProxyClass has some funky way of using
|
||||
* the incorrect class loader to resolve proxy classes, let's do it our way instead
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> resolveProxyClass(String[] interfaces)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ClassLoader latestLoader;
|
||||
if (classLoaders != null && classLoaders.length > 0) {
|
||||
latestLoader = classLoaders[0];
|
||||
} else {
|
||||
latestLoader = null;
|
||||
}
|
||||
ClassLoader nonPublicLoader = null;
|
||||
boolean hasNonPublicInterface = false;
|
||||
|
||||
// define proxy in class loader of non-public interface(s), if any
|
||||
Class<?>[] classObjs = new Class[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
Class<?> cl = this.resolveClass(interfaces[i]);
|
||||
if (latestLoader==null) latestLoader = cl.getClassLoader();
|
||||
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
|
||||
if (hasNonPublicInterface) {
|
||||
if (nonPublicLoader != cl.getClassLoader()) {
|
||||
throw new IllegalAccessError(
|
||||
sm.getString("replicationStream.conflict"));
|
||||
}
|
||||
} else {
|
||||
nonPublicLoader = cl.getClassLoader();
|
||||
hasNonPublicInterface = true;
|
||||
}
|
||||
}
|
||||
classObjs[i] = cl;
|
||||
}
|
||||
try {
|
||||
return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
|
||||
: latestLoader, classObjs);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ClassNotFoundException(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Class<?> findReplicationClass(String name)
|
||||
throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(name, false, getClass().getClassLoader());
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public Class<?> findExternalClass(String name) throws ClassNotFoundException {
|
||||
ClassNotFoundException cnfe = null;
|
||||
for (int i=0; i<classLoaders.length; i++ ) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(name, false, classLoaders[i]);
|
||||
return clazz;
|
||||
} catch ( ClassNotFoundException x ) {
|
||||
cnfe = x;
|
||||
}
|
||||
}
|
||||
if ( cnfe != null ) throw cnfe;
|
||||
else throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.classLoaders = null;
|
||||
super.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
596
java/org/apache/catalina/tribes/io/XByteBuffer.java
Normal file
596
java/org/apache/catalina/tribes/io/XByteBuffer.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user