diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/pom.xml b/dubbo-serialization-extensions/dubbo-serialization-jdk/pom.xml new file mode 100644 index 000000000..43525f81d --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/pom.xml @@ -0,0 +1,54 @@ + + + + 4.0.0 + + org.apache.dubbo.extensions + dubbo-serialization-extensions + ${revision} + ../pom.xml + + dubbo-serialization-jdk + jar + ${project.artifactId} + The jdk serialization module of dubbo project + ${revision} + + + 1.8 + 1.8 + UTF-8 + + + + org.apache.dubbo + dubbo-serialization-api + true + + + org.apache.dubbo + dubbo-common + true + + + com.alibaba + hessian-lite + + + diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java new file mode 100644 index 000000000..b87e75c00 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedJavaSerialization.java @@ -0,0 +1,58 @@ +/* + * 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.dubbo.common.serialize.java; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.Serialization; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import static org.apache.dubbo.common.serialize.Constants.COMPACTED_JAVA_SERIALIZATION_ID; + +/** + * Compacted java serialization implementation + * + *
+ *     e.g. <dubbo:protocol serialization="compactedjava" />
+ * 
+ */ +public class CompactedJavaSerialization implements Serialization { + + @Override + public byte getContentTypeId() { + return COMPACTED_JAVA_SERIALIZATION_ID; + } + + @Override + public String getContentType() { + return "x-application/compactedjava"; + } + + @Override + public ObjectOutput serialize(URL url, OutputStream out) throws IOException { + return new JavaObjectOutput(out, true); + } + + @Override + public ObjectInput deserialize(URL url, InputStream is) throws IOException { + return new JavaObjectInput(is, true); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java new file mode 100644 index 000000000..045fec3b1 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectInputStream.java @@ -0,0 +1,63 @@ +/* + * 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.dubbo.common.serialize.java; + +import org.apache.dubbo.common.utils.ClassUtils; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.io.StreamCorruptedException; + +/** + * Compacted java object input implementation + */ +public class CompactedObjectInputStream extends ObjectInputStream { + private ClassLoader mClassLoader; + + public CompactedObjectInputStream(InputStream in) throws IOException { + this(in, Thread.currentThread().getContextClassLoader()); + } + + public CompactedObjectInputStream(InputStream in, ClassLoader cl) throws IOException { + super(in); + mClassLoader = cl == null ? ClassUtils.getClassLoader() : cl; + } + + @Override + protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { + int type = read(); + if (type < 0) { + throw new EOFException(); + } + switch (type) { + case 0: + return super.readClassDescriptor(); + case 1: + Class clazz = loadClass(readUTF()); + return ObjectStreamClass.lookup(clazz); + default: + throw new StreamCorruptedException("Unexpected class descriptor type: " + type); + } + } + + private Class loadClass(String className) throws ClassNotFoundException { + return mClassLoader.loadClass(className); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java new file mode 100644 index 000000000..d93108311 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/CompactedObjectOutputStream.java @@ -0,0 +1,43 @@ +/* + * 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.dubbo.common.serialize.java; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.OutputStream; + +/** + * Compacted java object output implementation + */ +public class CompactedObjectOutputStream extends ObjectOutputStream { + public CompactedObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { + Class clazz = desc.forClass(); + if (clazz.isPrimitive() || clazz.isArray()) { + write(0); + super.writeClassDescriptor(desc); + } else { + write(1); + writeUTF(desc.getName()); + } + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java new file mode 100644 index 000000000..bbdd02ffa --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectInput.java @@ -0,0 +1,89 @@ +/* + * 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.dubbo.common.serialize.java; + +import org.apache.dubbo.common.serialize.nativejava.NativeJavaObjectInput; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.lang.reflect.Type; + +/** + * Java object input implementation + */ +public class JavaObjectInput extends NativeJavaObjectInput { + public static final int MAX_BYTE_ARRAY_LENGTH = 8 * 1024 * 1024; + + public JavaObjectInput(InputStream is) throws IOException { + super(new ObjectInputStream(is)); + } + + public JavaObjectInput(InputStream is, boolean compacted) throws IOException { + super(compacted ? new CompactedObjectInputStream(is) : new ObjectInputStream(is)); + } + + @Override + public byte[] readBytes() throws IOException { + int len = getObjectInputStream().readInt(); + if (len < 0) { + return null; + } + if (len == 0) { + return new byte[0]; + } + if (len > MAX_BYTE_ARRAY_LENGTH) { + throw new IOException("Byte array length too large. " + len); + } + + byte[] b = new byte[len]; + getObjectInputStream().readFully(b); + return b; + } + + @Override + public String readUTF() throws IOException { + int len = getObjectInputStream().readInt(); + if (len < 0) { + return null; + } + + return getObjectInputStream().readUTF(); + } + + @Override + public Object readObject() throws IOException, ClassNotFoundException { + byte b = getObjectInputStream().readByte(); + if (b == 0) { + return null; + } + + return getObjectInputStream().readObject(); + } + + @Override + @SuppressWarnings("unchecked") + public T readObject(Class cls) throws IOException, ClassNotFoundException { + return (T) readObject(); + } + + @Override + @SuppressWarnings("unchecked") + public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { + return (T) readObject(); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java new file mode 100644 index 000000000..0e78747c9 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaObjectOutput.java @@ -0,0 +1,61 @@ +/* + * 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.dubbo.common.serialize.java; + +import org.apache.dubbo.common.serialize.nativejava.NativeJavaObjectOutput; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +/** + * Java object output implementation + */ +public class JavaObjectOutput extends NativeJavaObjectOutput { + public JavaObjectOutput(OutputStream os) throws IOException { + super(new ObjectOutputStream(os)); + } + + public JavaObjectOutput(OutputStream os, boolean compact) throws IOException { + super(compact ? new CompactedObjectOutputStream(os) : new ObjectOutputStream(os)); + } + + @Override + public void writeUTF(String v) throws IOException { + if (v == null) { + getObjectOutputStream().writeInt(-1); + } else { + getObjectOutputStream().writeInt(v.length()); + getObjectOutputStream().writeUTF(v); + } + } + + @Override + public void writeObject(Object obj) throws IOException { + if (obj == null) { + getObjectOutputStream().writeByte(0); + } else { + getObjectOutputStream().writeByte(1); + getObjectOutputStream().writeObject(obj); + } + } + + @Override + public void flushBuffer() throws IOException { + getObjectOutputStream().flush(); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java new file mode 100644 index 000000000..1962ab412 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/java/JavaSerialization.java @@ -0,0 +1,82 @@ +/* + * 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.dubbo.common.serialize.java; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.Serialization; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSAFE_SERIALIZATION; +import static org.apache.dubbo.common.serialize.Constants.JAVA_SERIALIZATION_ID; + +/** + * Java serialization implementation + * + *
+ *     e.g. <dubbo:protocol serialization="java" />
+ * 
+ */ +public class JavaSerialization implements Serialization { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(JavaSerialization.class); + private static final AtomicBoolean warn = new AtomicBoolean(false); + + @Override + public byte getContentTypeId() { + return JAVA_SERIALIZATION_ID; + } + + @Override + public String getContentType() { + return "x-application/java"; + } + + @Override + public ObjectOutput serialize(URL url, OutputStream out) throws IOException { + if (warn.compareAndSet(false, true)) { + logger.error( + PROTOCOL_UNSAFE_SERIALIZATION, + "", + "", + "Java serialization is unsafe. Dubbo Team do not recommend anyone to use it." + + "If you still want to use it, please follow [JEP 290](https://openjdk.java.net/jeps/290)" + + "to set serialization filter to prevent deserialization leak."); + } + return new JavaObjectOutput(out); + } + + @Override + public ObjectInput deserialize(URL url, InputStream is) throws IOException { + if (warn.compareAndSet(false, true)) { + logger.error( + PROTOCOL_UNSAFE_SERIALIZATION, + "", + "", + "Java serialization is unsafe. Dubbo Team do not recommend anyone to use it." + + "If you still want to use it, please follow [JEP 290](https://openjdk.java.net/jeps/290)" + + "to set serialization filter to prevent deserialization leak."); + } + return new JavaObjectInput(is); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java new file mode 100644 index 000000000..74431832f --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectInput.java @@ -0,0 +1,117 @@ +/* + * 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.dubbo.common.serialize.nativejava; + +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.utils.Assert; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.lang.reflect.Type; + +/** + * Native java object input implementation + */ +public class NativeJavaObjectInput implements ObjectInput { + + private final ObjectInputStream inputStream; + + public NativeJavaObjectInput(InputStream is) throws IOException { + this(new ObjectInputStream(is)); + } + + protected NativeJavaObjectInput(ObjectInputStream is) { + Assert.notNull(is, "input == null"); + inputStream = is; + } + + protected ObjectInputStream getObjectInputStream() { + return inputStream; + } + + @Override + public Object readObject() throws IOException, ClassNotFoundException { + return inputStream.readObject(); + } + + @Override + @SuppressWarnings("unchecked") + public T readObject(Class cls) throws IOException, ClassNotFoundException { + return (T) readObject(); + } + + @Override + @SuppressWarnings("unchecked") + public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { + return (T) readObject(); + } + + @Override + public boolean readBool() throws IOException { + return inputStream.readBoolean(); + } + + @Override + public byte readByte() throws IOException { + return inputStream.readByte(); + } + + @Override + public short readShort() throws IOException { + return inputStream.readShort(); + } + + @Override + public int readInt() throws IOException { + return inputStream.readInt(); + } + + @Override + public long readLong() throws IOException { + return inputStream.readLong(); + } + + @Override + public float readFloat() throws IOException { + return inputStream.readFloat(); + } + + @Override + public double readDouble() throws IOException { + return inputStream.readDouble(); + } + + @Override + public String readUTF() throws IOException { + return inputStream.readUTF(); + } + + @Override + public byte[] readBytes() throws IOException { + int len = inputStream.readInt(); + if (len < 0) { + return null; + } else if (len == 0) { + return new byte[] {}; + } else { + byte[] result = new byte[len]; + inputStream.readFully(result); + return result; + } + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java new file mode 100644 index 000000000..a3274094d --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaObjectOutput.java @@ -0,0 +1,114 @@ +/* + * 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.dubbo.common.serialize.nativejava; + +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.utils.Assert; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +/** + * Native java object output implementation + */ +public class NativeJavaObjectOutput implements ObjectOutput { + + private final ObjectOutputStream outputStream; + + public NativeJavaObjectOutput(OutputStream os) throws IOException { + this(new ObjectOutputStream(os)); + } + + protected NativeJavaObjectOutput(ObjectOutputStream out) { + Assert.notNull(out, "output == null"); + this.outputStream = out; + } + + protected ObjectOutputStream getObjectOutputStream() { + return outputStream; + } + + @Override + public void writeObject(Object obj) throws IOException { + outputStream.writeObject(obj); + } + + @Override + public void writeBool(boolean v) throws IOException { + outputStream.writeBoolean(v); + } + + @Override + public void writeByte(byte v) throws IOException { + outputStream.writeByte(v); + } + + @Override + public void writeShort(short v) throws IOException { + outputStream.writeShort(v); + } + + @Override + public void writeInt(int v) throws IOException { + outputStream.writeInt(v); + } + + @Override + public void writeLong(long v) throws IOException { + outputStream.writeLong(v); + } + + @Override + public void writeFloat(float v) throws IOException { + outputStream.writeFloat(v); + } + + @Override + public void writeDouble(double v) throws IOException { + outputStream.writeDouble(v); + } + + @Override + public void writeUTF(String v) throws IOException { + outputStream.writeUTF(v); + } + + @Override + public void writeBytes(byte[] v) throws IOException { + if (v == null) { + outputStream.writeInt(-1); + } else { + writeBytes(v, 0, v.length); + } + } + + @Override + public void writeBytes(byte[] v, int off, int len) throws IOException { + if (v == null) { + outputStream.writeInt(-1); + } else { + outputStream.writeInt(len); + outputStream.write(v, off, len); + } + } + + @Override + public void flushBuffer() throws IOException { + outputStream.flush(); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java new file mode 100644 index 000000000..ea37e998a --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/java/org/apache/dubbo/common/serialize/nativejava/NativeJavaSerialization.java @@ -0,0 +1,83 @@ +/* + * 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.dubbo.common.serialize.nativejava; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.Serialization; +import org.apache.dubbo.common.serialize.java.JavaSerialization; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSAFE_SERIALIZATION; +import static org.apache.dubbo.common.serialize.Constants.NATIVE_JAVA_SERIALIZATION_ID; + +/** + * Native java serialization implementation + * + *
+ *     e.g. <dubbo:protocol serialization="nativejava" />
+ * 
+ */ +public class NativeJavaSerialization implements Serialization { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(JavaSerialization.class); + private static final AtomicBoolean warn = new AtomicBoolean(false); + + @Override + public byte getContentTypeId() { + return NATIVE_JAVA_SERIALIZATION_ID; + } + + @Override + public String getContentType() { + return "x-application/nativejava"; + } + + @Override + public ObjectOutput serialize(URL url, OutputStream output) throws IOException { + if (warn.compareAndSet(false, true)) { + logger.error( + PROTOCOL_UNSAFE_SERIALIZATION, + "", + "", + "Java serialization is unsafe. Dubbo Team do not recommend anyone to use it." + + "If you still want to use it, please follow [JEP 290](https://openjdk.java.net/jeps/290)" + + "to set serialization filter to prevent deserialization leak."); + } + return new NativeJavaObjectOutput(output); + } + + @Override + public ObjectInput deserialize(URL url, InputStream input) throws IOException { + if (warn.compareAndSet(false, true)) { + logger.error( + PROTOCOL_UNSAFE_SERIALIZATION, + "", + "", + "Java serialization is unsafe. Dubbo Team do not recommend anyone to use it." + + "If you still want to use it, please follow [JEP 290](https://openjdk.java.net/jeps/290)" + + "to set serialization filter to prevent deserialization leak."); + } + return new NativeJavaObjectInput(input); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization new file mode 100644 index 000000000..bc1e4ef00 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization @@ -0,0 +1,3 @@ +java=org.apache.dubbo.common.serialize.java.JavaSerialization +compactedjava=org.apache.dubbo.common.serialize.java.CompactedJavaSerialization +nativejava=org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization \ No newline at end of file diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/Image.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/Image.java new file mode 100644 index 000000000..b6a1b5453 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/Image.java @@ -0,0 +1,120 @@ +/* + * 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.dubbo.common.serialize.jdk; + + +public class Image implements java.io.Serializable { + private static final long serialVersionUID = 1L; + public String uri; + public String title; // Can be null + public int width; + public int height; + public Size size; + + public Image() { + } + + public Image(String uri, String title, int width, int height, Size size) { + this.height = height; + this.title = title; + this.uri = uri; + this.width = width; + this.size = size; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Image image = (Image) o; + + if (height != image.height) return false; + if (width != image.width) return false; + if (size != image.size) return false; + if (title != null ? !title.equals(image.title) : image.title != null) return false; + if (uri != null ? !uri.equals(image.uri) : image.uri != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = uri != null ? uri.hashCode() : 0; + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + width; + result = 31 * result + height; + result = 31 * result + (size != null ? size.hashCode() : 0); + return result; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[Image "); + sb.append("uri=").append(uri); + sb.append(", title=").append(title); + sb.append(", width=").append(width); + sb.append(", height=").append(height); + sb.append(", size=").append(size); + sb.append("]"); + return sb.toString(); + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + public enum Size { + SMALL, LARGE + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkObjectOutputTest.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkObjectOutputTest.java new file mode 100644 index 000000000..4043c0720 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkObjectOutputTest.java @@ -0,0 +1,147 @@ +/* + * 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.dubbo.common.serialize.jdk; + +import org.apache.dubbo.common.serialize.java.JavaObjectInput; +import org.apache.dubbo.common.serialize.java.JavaObjectOutput; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * {@link JavaObjectOutput} Unit Test + */ +public class JdkObjectOutputTest { + + private JavaObjectOutput javaObjectOutput; + private JavaObjectInput jdkObjectInput; + private ByteArrayOutputStream byteArrayOutputStream; + private ByteArrayInputStream byteArrayInputStream; + + @BeforeEach + public void setUp() throws Exception { + this.byteArrayOutputStream = new ByteArrayOutputStream(); + this.javaObjectOutput = new JavaObjectOutput(byteArrayOutputStream); + } + + @Test + public void testWriteBool() throws IOException { + this.javaObjectOutput.writeBool(true); + this.flushToInput(); + + assertThat(jdkObjectInput.readBool(), is(true)); + } + + @Test + public void testWriteShort() throws IOException { + this.javaObjectOutput.writeShort((short) 2); + this.flushToInput(); + + assertThat(jdkObjectInput.readShort(), is((short) 2)); + } + + @Test + public void testWriteInt() throws IOException { + this.javaObjectOutput.writeInt(1); + this.flushToInput(); + + assertThat(jdkObjectInput.readInt(), is(1)); + } + + @Test + public void testWriteLong() throws IOException { + this.javaObjectOutput.writeLong(1000L); + this.flushToInput(); + + assertThat(jdkObjectInput.readLong(), is(1000L)); + } + + @Test + public void testWriteUTF() throws IOException { + this.javaObjectOutput.writeUTF("Pace Hasîtî 和平 Мир"); + this.flushToInput(); + + assertThat(jdkObjectInput.readUTF(), is("Pace Hasîtî 和平 Мир")); + } + + + @Test + public void testWriteFloat() throws IOException { + this.javaObjectOutput.writeFloat(1.88f); + this.flushToInput(); + + assertThat(this.jdkObjectInput.readFloat(), is(1.88f)); + } + + @Test + public void testWriteDouble() throws IOException { + this.javaObjectOutput.writeDouble(1.66d); + this.flushToInput(); + + assertThat(this.jdkObjectInput.readDouble(), is(1.66d)); + } + + @Test + public void testWriteBytes() throws IOException { + this.javaObjectOutput.writeBytes("hello".getBytes()); + this.flushToInput(); + + assertThat(this.jdkObjectInput.readBytes(), is("hello".getBytes())); + } + + @Test + public void testWriteBytesWithSubLength() throws IOException { + this.javaObjectOutput.writeBytes("hello".getBytes(), 2, 2); + this.flushToInput(); + + assertThat(this.jdkObjectInput.readBytes(), is("ll".getBytes())); + } + + @Test + public void testWriteByte() throws IOException { + this.javaObjectOutput.writeByte((byte) 123); + this.flushToInput(); + + assertThat(this.jdkObjectInput.readByte(), is((byte) 123)); + } + + @Test + public void testWriteObject() throws IOException, ClassNotFoundException { + Image image = new Image("http://dubbo.apache.org/img/dubbo_white.png", "logo", 300, 480, Image.Size.SMALL); + this.javaObjectOutput.writeObject(image); + this.flushToInput(); + + Image readObjectForImage = jdkObjectInput.readObject(Image.class); + assertThat(readObjectForImage, not(nullValue())); + assertThat(readObjectForImage, is(image)); + } + + private void flushToInput() throws IOException { + this.javaObjectOutput.flushBuffer(); + this.byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + this.jdkObjectInput = new JavaObjectInput(byteArrayInputStream); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkSerializationTest.java b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkSerializationTest.java new file mode 100644 index 000000000..aa0ed6796 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-jdk/src/test/java/org/apache/dubbo/common/serialize/jdk/JdkSerializationTest.java @@ -0,0 +1,63 @@ +/* + * 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.dubbo.common.serialize.jdk; + +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.java.JavaObjectOutput; +import org.apache.dubbo.common.serialize.java.JavaSerialization; + +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.OutputStream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; + +/** + * {@link JavaSerialization} Unit Test + */ +public class JdkSerializationTest { + + private JavaSerialization JavaSerialization; + + @BeforeEach + public void setUp() { + this.JavaSerialization = new JavaSerialization(); + } + + @Test + public void testContentTypeId() { + MatcherAssert.assertThat(JavaSerialization.getContentTypeId(), is((byte) 3)); + } + + @Test + public void testContentType() { + MatcherAssert.assertThat(JavaSerialization.getContentType(), is("x-application/java")); + } + + @Test + public void testObjectOutput() throws IOException { + ObjectOutput objectOutput = JavaSerialization.serialize(null, mock(OutputStream.class)); + assertThat(objectOutput, Matchers.instanceOf(JavaObjectOutput.class)); + } + +} diff --git a/dubbo-serialization-extensions/pom.xml b/dubbo-serialization-extensions/pom.xml index 2a7eef1b4..cec14402b 100644 --- a/dubbo-serialization-extensions/pom.xml +++ b/dubbo-serialization-extensions/pom.xml @@ -44,6 +44,7 @@ dubbo-serialization-msgpack dubbo-serialization-native-hessian dubbo-serialization-jackson + dubbo-serialization-jdk dubbo-serialization-test dubbo-serialization-common diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/case-configuration.yml b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/case-configuration.yml new file mode 100644 index 000000000..10049efc1 --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/case-configuration.yml @@ -0,0 +1,24 @@ +# 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. + +from: app-builtin-zookeeper.yml + +props: + project_name: dubbo-serialization-jdk-test + main_class: org.apache.dubbo.test.serialization.jdk.JdkProvider + zookeeper_port: 2181 + dubbo_port: 20880 + diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/pom.xml b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/pom.xml new file mode 100644 index 000000000..a4e67778e --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/pom.xml @@ -0,0 +1,176 @@ + + + + scenarios-dubbo-serialization + org.apache.dubbo.extensions + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-serialization-jdk-test + + + 1.8 + 1.8 + 3.7.0 + + + + + + org.springframework + spring-framework-bom + ${spring.version} + pom + import + + + + org.apache.dubbo + dubbo-bom + ${dubbo.version} + pom + import + + + + org.apache.dubbo + dubbo-dependencies-zookeeper + ${dubbo.version} + pom + + + + junit + junit + ${junit.version} + + + + + + + org.apache.dubbo + dubbo + + + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + + ch.qos.logback + logback-classic + + + + org.xerial.snappy + snappy-java + ${snappy.version} + + + + org.apache.dubbo + dubbo-dependencies-zookeeper + pom + + + + junit + junit + test + + + + org.springframework + spring-test + test + + + + org.apache.dubbo.extensions + dubbo-serialization-jdk + ${revision} + + + + org.apache.dubbo.extensions + dubbo-serialization-testcase + ${revision} + + + + + + + + javax.annotation + + [1.11,) + + + + javax.annotation + javax.annotation-api + 1.3.2 + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${source.level} + ${target.level} + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.2.0 + + + copy-dependencies + prepare-package + + copy-dependencies + + + + ${project.build.directory}/lib + + + + + + + + + diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/EmbeddedZooKeeper.java b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/EmbeddedZooKeeper.java new file mode 100644 index 000000000..0615a14d6 --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/EmbeddedZooKeeper.java @@ -0,0 +1,254 @@ +/* + * + * 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.dubbo.test.serialization.jdk; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.SmartLifecycle; +import org.springframework.util.ErrorHandler; +import org.springframework.util.SocketUtils; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + *

+ * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + *

+ * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper implements SmartLifecycle { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + clientPort = SocketUtils.findAvailableTcpPort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + @Override + public int getPhase() { + return this.phase; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + *

+ * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + @Override + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + @Override + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + + File.separator + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/JdkProvider.java b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/JdkProvider.java new file mode 100644 index 000000000..9d1a1c502 --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/java/org/apache/dubbo/test/serialization/jdk/JdkProvider.java @@ -0,0 +1,39 @@ +/* + * + * 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.dubbo.test.serialization.jdk; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.concurrent.CountDownLatch; + +public class JdkProvider { + + public static void main(String[] args) throws Exception { + new EmbeddedZooKeeper(2181, false).start(); + // wait for embedded zookeeper start completely. + Thread.sleep(1000); + + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-provider.xml"); + context.start(); + + System.out.println("dubbo service started"); + new CountDownLatch(1).await(); + } +} diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/log4j.properties b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/log4j.properties new file mode 100644 index 000000000..1f8fe1ece --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/log4j.properties @@ -0,0 +1,25 @@ +# +# +# 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. +# +# +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-consumer.xml b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-consumer.xml new file mode 100644 index 000000000..62422373c --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-consumer.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-provider.xml b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-provider.xml new file mode 100644 index 000000000..851d3423b --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/main/resources/spring/dubbo-demo-provider.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/test/java/DemoServiceIT.java b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/test/java/DemoServiceIT.java new file mode 100644 index 000000000..437d019c9 --- /dev/null +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-jdk-test/src/test/java/DemoServiceIT.java @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ + +import org.apache.dubbo.test.serialization.testcase.BigPerson; +import org.apache.dubbo.test.serialization.testcase.DemoService; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.Random; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath*:spring/dubbo-demo-consumer.xml") +public class DemoServiceIT { + @Autowired + @Qualifier("demoService") + private DemoService service; + + + @Test + public void testVoid() throws Exception { + service.testVoid(); + } + + @Test + public void testString() throws Exception { + Assert.assertTrue(service.testString("world").endsWith("world")); + } + + @Test + public void testBase() throws Exception { + Random random = new Random(10000); + int num = random.nextInt(); + Assert.assertEquals(100 + num, service.testBase(num)); + } + + @Test + public void testObject() throws Exception { + BigPerson person = BigPerson.build(); + Assert.assertEquals(service.testObject(person), person); + } +} diff --git a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-protostuff-test/src/main/java/org/apache/dubbo/test/serialization/protostuff/EmbeddedZooKeeper.java b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-protostuff-test/src/main/java/org/apache/dubbo/test/serialization/protostuff/EmbeddedZooKeeper.java index c126e2629..05219053c 100644 --- a/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-protostuff-test/src/main/java/org/apache/dubbo/test/serialization/protostuff/EmbeddedZooKeeper.java +++ b/test/scenarios/scenarios-dubbo-serialization/dubbo-serialization-protostuff-test/src/main/java/org/apache/dubbo/test/serialization/protostuff/EmbeddedZooKeeper.java @@ -1,17 +1,20 @@ /* - * Copyright 2014 the original author or authors. * - * Licensed 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 + * 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 + * 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. * - * 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.dubbo.test.serialization.protostuff; diff --git a/test/scenarios/scenarios-dubbo-serialization/pom.xml b/test/scenarios/scenarios-dubbo-serialization/pom.xml index 07d5fc3b4..23c122b80 100644 --- a/test/scenarios/scenarios-dubbo-serialization/pom.xml +++ b/test/scenarios/scenarios-dubbo-serialization/pom.xml @@ -36,6 +36,7 @@ dubbo-serialization-kryo-test dubbo-serialization-protobuf-test dubbo-serialization-protostuff-test + dubbo-serialization-jdk-test dubbo-serialization-testcase