View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.serialization;
17  
18  import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
19  
20  import io.netty.buffer.ByteBuf;
21  import io.netty.buffer.ByteBufOutputStream;
22  import io.netty.channel.ChannelHandlerContext;
23  import io.netty.handler.codec.MessageToByteEncoder;
24  
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.io.OutputStream;
28  import java.io.Serializable;
29  
30  /**
31   * An encoder which serializes a Java object into a {@link ByteBuf}
32   * (interoperability version).
33   * <p>
34   * This encoder is interoperable with the standard Java object streams such as
35   * {@link ObjectInputStream} and {@link ObjectOutputStream}.
36   * <p>
37   * <strong>Security:</strong> serialization can be a security liability,
38   * and should not be used without defining a list of classes that are
39   * allowed to be desirialized. Such a list can be specified with the
40   * <tt>jdk.serialFilter</tt> system property, for instance.
41   * See the <a href="https://docs.oracle.com/en/java/javase/17/core/serialization-filtering1.html">
42   * serialization filtering</a> article for more information.
43   *
44   * @deprecated This class has been deprecated with no replacement,
45   * because serialization can be a security liability
46   */
47  @Deprecated
48  public class CompatibleObjectEncoder extends MessageToByteEncoder<Serializable> {
49      private final int resetInterval;
50      private int writtenObjects;
51  
52      /**
53       * Creates a new instance with the reset interval of {@code 16}.
54       */
55      public CompatibleObjectEncoder() {
56          this(16); // Reset at every sixteen writes
57      }
58  
59      /**
60       * Creates a new instance.
61       *
62       * @param resetInterval
63       *        the number of objects between {@link ObjectOutputStream#reset()}.
64       *        {@code 0} will disable resetting the stream, but the remote
65       *        peer will be at the risk of getting {@link OutOfMemoryError} in
66       *        the long term.
67       */
68      public CompatibleObjectEncoder(int resetInterval) {
69          this.resetInterval = checkPositiveOrZero(resetInterval, "resetInterval");
70      }
71  
72      /**
73       * Creates a new {@link ObjectOutputStream} which wraps the specified
74       * {@link OutputStream}.  Override this method to use a subclass of the
75       * {@link ObjectOutputStream}.
76       */
77      protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws Exception {
78          return new ObjectOutputStream(out);
79      }
80  
81      @Override
82      protected void encode(ChannelHandlerContext ctx, Serializable msg, ByteBuf out) throws Exception {
83          // Suppress a warning about resource leak since oss is closed below
84          ObjectOutputStream oos = newObjectOutputStream(
85                  new ByteBufOutputStream(out));
86          try {
87              if (resetInterval != 0) {
88                  // Resetting will prevent OOM on the receiving side.
89                  writtenObjects ++;
90                  if (writtenObjects % resetInterval == 0) {
91                      oos.reset();
92                  }
93              }
94  
95              oos.writeObject(msg);
96              oos.flush();
97          } finally {
98              oos.close();
99          }
100     }
101 }