类java.io.ObjectInputFilter源码实例Demo

下面列出了怎么用java.io.ObjectInputFilter的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: openjdk-jdk9   文件: MarshalledObject.java
/**
 * Creates a new <code>MarshalledObjectInputStream</code> that
 * reads its objects from <code>objIn</code> and annotations
 * from <code>locIn</code>.  If <code>locIn</code> is
 * <code>null</code>, then all annotations will be
 * <code>null</code>.
 */
MarshalledObjectInputStream(InputStream objIn, InputStream locIn,
            ObjectInputFilter filter)
    throws IOException
{
    super(objIn);
    this.locIn = (locIn == null ? null : new ObjectInputStream(locIn));
    if (filter != null) {
        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
            MarshalledObjectInputStream.this.setObjectInputFilter(filter);
            if (MarshalledObjectInputStream.this.locIn != null) {
                MarshalledObjectInputStream.this.locIn.setObjectInputFilter(filter);
            }
            return null;
        });
    }
}
 
源代码2 项目: openjdk-jdk9   文件: RegistryImpl.java
/**
 * Initialize the registryFilter from the security properties or system property; if any
 * @return an ObjectInputFilter, or null
 */
@SuppressWarnings("deprecation")
private static ObjectInputFilter initRegistryFilter() {
    ObjectInputFilter filter = null;
    String props = System.getProperty(REGISTRY_FILTER_PROPNAME);
    if (props == null) {
        props = Security.getProperty(REGISTRY_FILTER_PROPNAME);
    }
    if (props != null) {
        filter = ObjectInputFilter.Config.createFilter(props);
        Log regLog = Log.getLog("sun.rmi.registry", "registry", -1);
        if (regLog.isLoggable(Log.BRIEF)) {
            regLog.log(Log.BRIEF, "registryFilter = " + filter);
        }
    }
    return filter;
}
 
源代码3 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Read objects from the serialized stream, validated with the filter.
 *
 * @param bytes a byte array to read objects from
 * @param filter the ObjectInputFilter
 * @return the object deserialized if any
 * @throws IOException can be thrown
 */
static Object validate(byte[] bytes,
                     ObjectInputFilter filter) throws IOException {
    try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
         ObjectInputStream ois = new ObjectInputStream(bais)) {
        ois.setObjectInputFilter(filter);

        Object o = ois.readObject();
        return o;
    } catch (EOFException eof) {
        // normal completion
    } catch (ClassNotFoundException cnf) {
        Assert.fail("Deserializing", cnf);
    }
    return null;
}
 
源代码4 项目: openjdk-jdk9   文件: SerialFilterTest.java
@Override
public ObjectInputFilter.Status checkInput(FilterInfo filter) {
    Class<?> serialClass = filter.serialClass();
    System.out.printf("     checkInput: class: %s, arrayLen: %d, refs: %d, depth: %d, bytes; %d%n",
            serialClass, filter.arrayLength(), filter.references(),
            filter.depth(), filter.streamBytes());
    count++;
    if (serialClass != null) {
        if (serialClass.getName().contains("$$Lambda$")) {
            // TBD: proper identification of serialized Lambdas?
            // Fold the serialized Lambda into the SerializedLambda type
            classes.add(SerializedLambda.class);
        } else if (Proxy.isProxyClass(serialClass)) {
            classes.add(Proxy.class);
        } else {
            classes.add(serialClass);
        }

    }
    this.maxArray = Math.max(this.maxArray, filter.arrayLength());
    this.maxRefs = Math.max(this.maxRefs, filter.references());
    this.maxDepth = Math.max(this.maxDepth, filter.depth());
    this.maxBytes = Math.max(this.maxBytes, filter.streamBytes());
    return ObjectInputFilter.Status.UNDECIDED;
}
 
/**
 * Test that setting process-wide filter is checked by security manager.
 */
@Test
public void testGlobalFilter() throws Exception {
    ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();

    try  {
        ObjectInputFilter.Config.setSerialFilter(filter);
        assertFalse(setSecurityManager,
                "When SecurityManager exists, without "
                + "java.io.SerializablePermission(serialFilter) "
                + "IllegalStateException should be thrown");
    } catch (AccessControlException ex) {
        assertTrue(setSecurityManager);
        assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
        assertTrue(ex.getMessage().contains("serialFilter"));
    } catch (IllegalStateException ise) {
        // ISE should occur only if global filter already set
        Assert.assertNotNull(global, "Global filter should be non-null");
    }
}
 
源代码6 项目: logging-log4j2   文件: DefaultObjectInputFilter.java
@Override
public Status checkInput(FilterInfo filterInfo) {
    Status status = null;
    if (delegate != null) {
        status = delegate.checkInput(filterInfo);
        if (status != Status.UNDECIDED) {
            return status;
        }
    }
    ObjectInputFilter serialFilter = ObjectInputFilter.Config.getSerialFilter();
    if (serialFilter != null) {
        status = serialFilter.checkInput(filterInfo);
        if (status != Status.UNDECIDED) {
            // The process-wide filter overrides this filter
            return status;
        }
    }
    if (filterInfo.serialClass() != null) {
        String name = filterInfo.serialClass().getName();
        if (isAllowedByDefault(name) || isRequiredPackage(name)) {
            return Status.ALLOWED;
        }
    }
    return Status.REJECTED;
}
 
源代码7 项目: openjdk-jdk9   文件: SingleEntryRegistry.java
/**
 * ObjectInputFilter to check parameters to SingleEntryRegistry.
 * Since it is a read-only Registry, no classes are accepted.
 * String arguments are accepted without passing them to the serialFilter.
 *
 * @param info a reference to the serialization filter information
 * @return Status.REJECTED if parameters are out of range
 */
private static ObjectInputFilter.Status singleRegistryFilter(ObjectInputFilter.FilterInfo info) {
    return (info.serialClass() != null ||
            info.depth() > 2 ||
            info.references() > 4 ||
            info.arrayLength() >= 0)
    ? ObjectInputFilter.Status.REJECTED
    : ObjectInputFilter.Status.ALLOWED;
}
 
源代码8 项目: openjdk-jdk9   文件: DGCImpl_Stub.java
/**
 * ObjectInputFilter to filter DGCClient return value (a Lease).
 * The list of acceptable classes is very short and explicit.
 * The depth and array sizes are limited.
 *
 * @param filterInfo access to class, arrayLength, etc.
 * @return  {@link ObjectInputFilter.Status#ALLOWED} if allowed,
 *          {@link ObjectInputFilter.Status#REJECTED} if rejected,
 *          otherwise {@link ObjectInputFilter.Status#UNDECIDED}
 */
private static ObjectInputFilter.Status leaseFilter(ObjectInputFilter.FilterInfo filterInfo) {

    if (filterInfo.depth() > DGCCLIENT_MAX_DEPTH) {
        return ObjectInputFilter.Status.REJECTED;
    }
    Class<?> clazz = filterInfo.serialClass();
    if (clazz != null) {
        while (clazz.isArray()) {
            if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > DGCCLIENT_MAX_ARRAY_SIZE) {
                return ObjectInputFilter.Status.REJECTED;
            }
            // Arrays are allowed depending on the component type
            clazz = clazz.getComponentType();
        }
        if (clazz.isPrimitive()) {
            // Arrays of primitives are allowed
            return ObjectInputFilter.Status.ALLOWED;
        }
        return (clazz == UID.class ||
                clazz == VMID.class ||
                clazz == Lease.class)
                ? ObjectInputFilter.Status.ALLOWED
                : ObjectInputFilter.Status.REJECTED;
    }
    // Not a class, not size limited
    return ObjectInputFilter.Status.UNDECIDED;
}
 
源代码9 项目: openjdk-jdk9   文件: DGCImpl.java
/**
 * Initialize the dgcFilter from the security properties or system property; if any
 * @return an ObjectInputFilter, or null
 */
private static ObjectInputFilter initDgcFilter() {
    ObjectInputFilter filter = null;
    String props = System.getProperty(DGC_FILTER_PROPNAME);
    if (props == null) {
        props = Security.getProperty(DGC_FILTER_PROPNAME);
    }
    if (props != null) {
        filter = ObjectInputFilter.Config.createFilter(props);
        if (dgcLog.isLoggable(Log.BRIEF)) {
            dgcLog.log(Log.BRIEF, "dgcFilter = " + filter);
        }
    }
    return filter;
}
 
源代码10 项目: openjdk-jdk9   文件: DGCImpl.java
/**
 * ObjectInputFilter to filter DGC input objects.
 * The list of acceptable classes is very short and explicit.
 * The depth and array sizes are limited.
 *
 * @param filterInfo access to class, arrayLength, etc.
 * @return  {@link ObjectInputFilter.Status#ALLOWED} if allowed,
 *          {@link ObjectInputFilter.Status#REJECTED} if rejected,
 *          otherwise {@link ObjectInputFilter.Status#UNDECIDED}
 */
private static ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo filterInfo) {
    if (dgcFilter != null) {
        ObjectInputFilter.Status status = dgcFilter.checkInput(filterInfo);
        if (status != ObjectInputFilter.Status.UNDECIDED) {
            // The DGC filter can override the built-in white-list
            return status;
        }
    }

    if (filterInfo.depth() > DGC_MAX_DEPTH) {
        return ObjectInputFilter.Status.REJECTED;
    }
    Class<?> clazz = filterInfo.serialClass();
    if (clazz != null) {
        while (clazz.isArray()) {
            if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > DGC_MAX_ARRAY_SIZE) {
                return ObjectInputFilter.Status.REJECTED;
            }
            // Arrays are allowed depending on the component type
            clazz = clazz.getComponentType();
        }
        if (clazz.isPrimitive()) {
            // Arrays of primitives are allowed
            return ObjectInputFilter.Status.ALLOWED;
        }
        return (clazz == ObjID.class ||
                clazz == UID.class ||
                clazz == VMID.class ||
                clazz == Lease.class)
                ? ObjectInputFilter.Status.ALLOWED
                : ObjectInputFilter.Status.REJECTED;
    }
    // Not a class, not size limited
    return ObjectInputFilter.Status.UNDECIDED;
}
 
源代码11 项目: openjdk-jdk9   文件: UnicastServerRef2.java
/**
 * Construct a Unicast server remote reference to be exported
 * on the specified port.
 */
public UnicastServerRef2(int port,
                         RMIClientSocketFactory csf,
                         RMIServerSocketFactory ssf,
                         ObjectInputFilter filter)
{
    super(new LiveRef(port, csf, ssf), filter);
}
 
源代码12 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Test that the filter on a OIS can be set only on a fresh OIS,
 * before deserializing any objects.
 * This test is agnostic the global filter being set or not.
 */
@Test
static void nonResettableFilter() {
    Validator validator1 = new Validator();
    Validator validator2 = new Validator();

    try {
        byte[] bytes = writeObjects("text1");    // an object

        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            // Check the initial filter is the global filter; may be null
            ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
            ObjectInputFilter initial = ois.getObjectInputFilter();
            Assert.assertEquals(global, initial, "initial filter should be the global filter");

            // Check if it can be set to null
            ois.setObjectInputFilter(null);
            ObjectInputFilter filter = ois.getObjectInputFilter();
            Assert.assertNull(filter, "set to null should be null");

            ois.setObjectInputFilter(validator1);
            Object o = ois.readObject();
            try {
                ois.setObjectInputFilter(validator2);
                Assert.fail("Should not be able to set filter twice");
            } catch (IllegalStateException ise) {
                // success, the exception was expected
            }
        } catch (EOFException eof) {
            Assert.fail("Should not reach end-of-file", eof);
        } catch (ClassNotFoundException cnf) {
            Assert.fail("Deserializing", cnf);
        }
    } catch (IOException ex) {
        Assert.fail("Unexpected IOException", ex);
    }
}
 
源代码13 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Test repeated limits use the last value.
 * Construct a filter with the limit and the limit repeated -1.
 * Invoke the filter with the limit to make sure it is rejected.
 * Invoke the filter with the limit -1 to make sure it is accepted.
 * @param name the name of the limit to test
 * @param value a test value
 */
@Test(dataProvider="Limits")
static void testLimits(String name, long value) {
    Class<?> arrayClass = new int[0].getClass();
    String pattern = String.format("%s=%d;%s=%d", name, value, name, value - 1);
    ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
    Assert.assertEquals(
            filter.checkInput(new FilterValues(arrayClass, value, value, value, value)),
            ObjectInputFilter.Status.REJECTED,
            "last limit value not used: " + filter);
    Assert.assertEquals(
            filter.checkInput(new FilterValues(arrayClass, value-1, value-1, value-1, value-1)),
            ObjectInputFilter.Status.UNDECIDED,
            "last limit value not used: " + filter);
}
 
源代码14 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Test invalid limits.
 * Construct a filter with the limit, it should throw IllegalArgumentException.
 * @param pattern a pattern to test
 */
@Test(dataProvider="InvalidLimits", expectedExceptions=java.lang.IllegalArgumentException.class)
static void testInvalidLimits(String pattern) {
    try {
        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
    } catch (IllegalArgumentException iae) {
        System.out.printf("    success exception: %s%n", iae);
        throw iae;
    }
}
 
源代码15 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Test that returning null from a filter causes deserialization to fail.
 */
@Test(expectedExceptions=InvalidClassException.class)
static void testNullStatus() throws IOException {
    byte[] bytes = writeObjects(0); // an Integer
    try {
        Object o = validate(bytes, new ObjectInputFilter() {
            public ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo f) {
                return null;
            }
        });
    } catch (InvalidClassException ice) {
        System.out.printf("    success exception: %s%n", ice);
        throw ice;
    }
}
 
源代码16 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Verify that malformed patterns throw IAE.
 * @param pattern pattern from the data source
 */
@Test(dataProvider="InvalidPatterns", expectedExceptions=IllegalArgumentException.class)
static void testInvalidPatterns(String pattern) {
    try {
        ObjectInputFilter.Config.createFilter(pattern);
    } catch (IllegalArgumentException iae) {
        System.out.printf("    success exception: %s%n", iae);
        throw iae;
    }
}
 
源代码17 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Test that Config.create returns null if the argument does not contain any patterns or limits.
 */
@Test()
static void testEmptyPattern() {
    ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("");
    Assert.assertNull(filter, "empty pattern did not return null");

    filter = ObjectInputFilter.Config.createFilter(";;;;");
    Assert.assertNull(filter, "pattern with only delimiters did not return null");
}
 
源代码18 项目: openjdk-jdk9   文件: SerialFilterTest.java
/**
 * Create a filter from a pattern and API factory, then serialize and
 * deserialize an object and check allowed or reject.
 *
 * @param pattern the pattern
 * @param object the test object
 * @param allowed the expected result from ObjectInputStream (exception or not)
 */
static void testPatterns(String pattern, Object object, boolean allowed) {
    try {
        byte[] bytes = SerialFilterTest.writeObjects(object);
        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
        validate(bytes, filter);
        Assert.assertTrue(allowed, "filter should have thrown an exception");
    } catch (IllegalArgumentException iae) {
        Assert.fail("bad format pattern", iae);
    } catch (InvalidClassException ice) {
        Assert.assertFalse(allowed, "filter should not have thrown an exception: " + ice);
    } catch (IOException ioe) {
        Assert.fail("Unexpected IOException", ioe);
    }
}
 
源代码19 项目: openjdk-jdk9   文件: SerialFilterTest.java
@Override
public ObjectInputFilter.Status checkInput(FilterInfo filter) {
    if (ReadResolveToArray.class.isAssignableFrom(filter.serialClass())) {
        return ObjectInputFilter.Status.ALLOWED;
    }
    if (filter.serialClass() != array.getClass() ||
            (filter.arrayLength() >= 0 && filter.arrayLength() != length)) {
        return ObjectInputFilter.Status.REJECTED;
    }
    return ObjectInputFilter.Status.UNDECIDED;
}
 
源代码20 项目: openjdk-jdk9   文件: GlobalFilterTest.java
/**
 * Test that the process-wide filter is set when the properties are set
 * and has the toString matching the configured pattern.
 */
@Test()
static void globalFilter() {
    String pattern =
            System.getProperty("jdk.serialFilter",
                    Security.getProperty("jdk.serialFilter"));
    ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
    System.out.printf("global pattern: %s, filter: %s%n", pattern, filter);
    Assert.assertEquals(pattern, Objects.toString(filter, null),
            "process-wide filter pattern does not match");
}
 
源代码21 项目: openjdk-jdk9   文件: CheckInputOrderTest.java
/**
 * Test:
 *   "global filter reject" + "specific ObjectInputStream filter is empty" => should reject
 *   "global filter reject" + "specific ObjectInputStream filter allow"    => should allow
 */
@Test(dataProvider="Patterns")
public void testRejectedInGlobal(Object toDeserialized, String pattern, boolean allowed) throws Exception {
    byte[] bytes = SerialFilterTest.writeObjects(toDeserialized);
    ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);

    try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais)) {
        ois.setObjectInputFilter(filter);
        Object o = ois.readObject();
        assertTrue(allowed, "filter should have thrown an exception");
    } catch (InvalidClassException ice) {
        assertFalse(allowed, "filter should have thrown an exception");
    }
}
 
@BeforeClass
public void setup() throws Exception {
    setSecurityManager = System.getSecurityManager() != null;
    Object toDeserialized = Long.MAX_VALUE;
    bytes = SerialFilterTest.writeObjects(toDeserialized);
    filter = ObjectInputFilter.Config.createFilter("java.lang.Long");
}
 
源代码23 项目: Bytecoder   文件: SharedSecrets.java
public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
    if (javaObjectInputFilterAccess == null) {
        unsafe.ensureClassInitialized(ObjectInputFilter.Config.class);
    }
    return javaObjectInputFilterAccess;
}
 
源代码24 项目: openjdk-jdk9   文件: UnicastServerRef2.java
/**
 * Construct a Unicast server remote reference for a specified
 * liveRef and filter.
 */
public UnicastServerRef2(LiveRef ref,
                         ObjectInputFilter filter)
{
    super(ref, filter);
}
 
源代码25 项目: openjdk-jdk9   文件: UnicastServerRef.java
/**
 * Construct a Unicast server remote reference for a specified
 * liveRef and filter.
 */
public UnicastServerRef(LiveRef ref, ObjectInputFilter filter) {
    super(ref);
    this.filter = filter;
}
 
源代码26 项目: openjdk-jdk9   文件: RegistryImpl.java
/**
 * ObjectInputFilter to filter Registry input objects.
 * The list of acceptable classes is limited to classes normally
 * stored in a registry.
 *
 * @param filterInfo access to the class, array length, etc.
 * @return  {@link ObjectInputFilter.Status#ALLOWED} if allowed,
 *          {@link ObjectInputFilter.Status#REJECTED} if rejected,
 *          otherwise {@link ObjectInputFilter.Status#UNDECIDED}
 */
private static ObjectInputFilter.Status registryFilter(ObjectInputFilter.FilterInfo filterInfo) {
    if (registryFilter != null) {
        ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo);
        if (status != ObjectInputFilter.Status.UNDECIDED) {
            // The Registry filter can override the built-in white-list
            return status;
        }
    }

    if (filterInfo.depth() > REGISTRY_MAX_DEPTH) {
        return ObjectInputFilter.Status.REJECTED;
    }
    Class<?> clazz = filterInfo.serialClass();
    if (clazz != null) {
        if (clazz.isArray()) {
            if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) {
                return ObjectInputFilter.Status.REJECTED;
            }
            do {
                // Arrays are allowed depending on the component type
                clazz = clazz.getComponentType();
            } while (clazz.isArray());
        }
        if (clazz.isPrimitive()) {
            // Arrays of primitives are allowed
            return ObjectInputFilter.Status.ALLOWED;
        }
        if (String.class == clazz
                || java.lang.Number.class.isAssignableFrom(clazz)
                || Remote.class.isAssignableFrom(clazz)
                || java.lang.reflect.Proxy.class.isAssignableFrom(clazz)
                || UnicastRef.class.isAssignableFrom(clazz)
                || RMIClientSocketFactory.class.isAssignableFrom(clazz)
                || RMIServerSocketFactory.class.isAssignableFrom(clazz)
                || java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)
                || java.rmi.server.UID.class.isAssignableFrom(clazz)) {
            return ObjectInputFilter.Status.ALLOWED;
        } else {
            return ObjectInputFilter.Status.REJECTED;
        }
    }
    return ObjectInputFilter.Status.UNDECIDED;
}
 
源代码27 项目: logging-log4j2   文件: DefaultObjectInputFilter.java
public DefaultObjectInputFilter(ObjectInputFilter filter) {
    delegate = filter;
}
 
源代码28 项目: openjdk-jdk9   文件: UnicastRemoteObject.java
/**
 * Exports the remote object to make it available to receive incoming
 * calls, using the particular supplied port
 * and {@linkplain ObjectInputFilter filter}.
 *
 * <p>The object is exported with a server socket
 * created using the {@link RMISocketFactory} class.
 *
 * @param obj the remote object to be exported
 * @param port the port to export the object on
 * @param filter an ObjectInputFilter applied when deserializing invocation arguments;
 *               may be {@code null}
 * @return remote object stub
 * @exception RemoteException if export fails
 * @since 9
 */
public static Remote exportObject(Remote obj, int port,
                                  ObjectInputFilter filter)
        throws RemoteException
{
    return exportObject(obj, new UnicastServerRef(new LiveRef(port), filter));
}
 
源代码29 项目: openjdk-jdk9   文件: UnicastRemoteObject.java
/**
 * Exports the remote object to make it available to receive incoming
 * calls, using a transport specified by the given socket factory
 * and {@linkplain ObjectInputFilter filter}.
 *
 * <p>Either socket factory may be {@code null}, in which case
 * the corresponding client or server socket creation method of
 * {@link RMISocketFactory} is used instead.
 *
 * @param obj the remote object to be exported
 * @param port the port to export the object on
 * @param csf the client-side socket factory for making calls to the
 * remote object
 * @param ssf the server-side socket factory for receiving remote calls
 * @param filter an ObjectInputFilter applied when deserializing invocation arguments;
 *               may be {@code null}
 * @return remote object stub
 * @exception RemoteException if export fails
 * @since 9
 */
public static Remote exportObject(Remote obj, int port,
                                  RMIClientSocketFactory csf,
                                  RMIServerSocketFactory ssf,
                                  ObjectInputFilter filter)
    throws RemoteException
{
    return exportObject(obj, new UnicastServerRef2(port, csf, ssf, filter));
}
 
源代码30 项目: Bytecoder   文件: JavaObjectInputFilterAccess.java
/**
 * Creates a filter from the pattern.
 */
ObjectInputFilter createFilter2(String pattern);
 
 类所在包
 类方法
 同包方法