8051422: Remove JNDI dependency on java.applet.Applet
Reviewed-by: alanb, chegar
This commit is contained in:
parent
924b9f9fde
commit
5a7fabe3e0
@ -165,6 +165,7 @@ public class CorbaUtils {
|
||||
|
||||
// Get Applet from environment
|
||||
if (env != null) {
|
||||
@SuppressWarnings("deprecation")
|
||||
Applet applet = (Applet) env.get(Context.APPLET);
|
||||
if (applet != null) {
|
||||
// Create ORBs using applet and orbProp
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,8 +28,6 @@ package com.sun.naming.internal;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
@ -126,52 +124,6 @@ public final class ResourceManager {
|
||||
private static final WeakReference<Object> NO_FACTORY =
|
||||
new WeakReference<>(null);
|
||||
|
||||
/**
|
||||
* A class to allow JNDI properties be specified as applet parameters
|
||||
* without creating a static dependency on java.applet.
|
||||
*/
|
||||
private static class AppletParameter {
|
||||
private static final Class<?> clazz = getClass("java.applet.Applet");
|
||||
private static final Method getMethod =
|
||||
getMethod(clazz, "getParameter", String.class);
|
||||
private static Class<?> getClass(String name) {
|
||||
try {
|
||||
return Class.forName(name, true, null);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static Method getMethod(Class<?> clazz,
|
||||
String name,
|
||||
Class<?>... paramTypes)
|
||||
{
|
||||
if (clazz != null) {
|
||||
try {
|
||||
return clazz.getMethod(name, paramTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the applet's named parameter.
|
||||
*/
|
||||
static Object get(Object applet, String name) {
|
||||
// if clazz is null then applet cannot be an Applet.
|
||||
if (clazz == null || !clazz.isInstance(applet))
|
||||
throw new ClassCastException(applet.getClass().getName());
|
||||
try {
|
||||
return getMethod.invoke(applet, name);
|
||||
} catch (InvocationTargetException |
|
||||
IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There should be no instances of this class.
|
||||
private ResourceManager() {
|
||||
}
|
||||
@ -179,12 +131,11 @@ public final class ResourceManager {
|
||||
|
||||
// ---------- Public methods ----------
|
||||
|
||||
/*
|
||||
/**
|
||||
* Given the environment parameter passed to the initial context
|
||||
* constructor, returns the full environment for that initial
|
||||
* context (never null). This is based on the environment
|
||||
* parameter, the applet parameters (where appropriate), the
|
||||
* system properties, and all application resource files.
|
||||
* parameter, the system properties, and all application resource files.
|
||||
*
|
||||
* <p> This method will modify <tt>env</tt> and save
|
||||
* a reference to it. The caller may no longer modify it.
|
||||
@ -196,18 +147,16 @@ public final class ResourceManager {
|
||||
* resource file
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Hashtable<?, ?> getInitialEnvironment(
|
||||
Hashtable<?, ?> env)
|
||||
public static Hashtable<?, ?> getInitialEnvironment(Hashtable<?, ?> env)
|
||||
throws NamingException
|
||||
{
|
||||
String[] props = VersionHelper.PROPS; // system/applet properties
|
||||
String[] props = VersionHelper.PROPS; // system properties
|
||||
if (env == null) {
|
||||
env = new Hashtable<>(11);
|
||||
}
|
||||
Object applet = env.get(Context.APPLET);
|
||||
|
||||
// Merge property values from env param, applet params, and system
|
||||
// properties. The first value wins: there's no concatenation of
|
||||
// Merge property values from env param, and system properties.
|
||||
// The first value wins: there's no concatenation of
|
||||
// colon-separated lists.
|
||||
// Read system properties by first trying System.getProperties(),
|
||||
// and then trying System.getProperty() if that fails. The former
|
||||
@ -216,10 +165,6 @@ public final class ResourceManager {
|
||||
String[] jndiSysProps = helper.getJndiProperties();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object val = env.get(props[i]);
|
||||
if (val == null) {
|
||||
if (applet != null) {
|
||||
val = AppletParameter.get(applet, props[i]);
|
||||
}
|
||||
if (val == null) {
|
||||
// Read system property.
|
||||
val = (jndiSysProps != null)
|
||||
@ -230,7 +175,6 @@ public final class ResourceManager {
|
||||
((Hashtable<String, Object>)env).put(props[i], val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return without merging if application resource files lookup
|
||||
// is disabled.
|
||||
@ -248,8 +192,8 @@ public final class ResourceManager {
|
||||
/**
|
||||
* Retrieves the property from the environment, or from the provider
|
||||
* resource file associated with the given context. The environment
|
||||
* may in turn contain values that come from applet parameters,
|
||||
* system properties, or application resource files.
|
||||
* may in turn contain values that come from system properties,
|
||||
* or application resource files.
|
||||
*
|
||||
* If <tt>concat</tt> is true and both the environment and the provider
|
||||
* resource file contain the property, the two values are concatenated
|
||||
@ -289,7 +233,7 @@ public final class ResourceManager {
|
||||
* property.
|
||||
*
|
||||
* The property is gotten from the environment and the provider
|
||||
* resource file associated with the given context and concantenated.
|
||||
* resource file associated with the given context and concatenated.
|
||||
* See getProperty(). The resulting property value is a list of class names.
|
||||
*<p>
|
||||
* This method then loads each class using the current thread's context
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -203,9 +203,7 @@ import java.util.Hashtable;
|
||||
* <h2>Application Resource Files</h2>
|
||||
*
|
||||
* When an application is deployed, it will generally have several
|
||||
* codebase directories and JARs in its classpath. Similarly, when an
|
||||
* applet is deployed, it will have a codebase and archives specifying
|
||||
* where to find the applet's classes. JNDI locates (using
|
||||
* codebase directories and JARs in its classpath. JNDI locates (using
|
||||
* {@link ClassLoader#getResources <tt>ClassLoader.getResources()</tt>})
|
||||
* all <em>application resource files</em> named <tt>jndi.properties</tt>
|
||||
* in the classpath.
|
||||
@ -236,7 +234,7 @@ import java.util.Hashtable;
|
||||
*
|
||||
* When JNDI constructs an initial context, the context's environment
|
||||
* is initialized with properties defined in the environment parameter
|
||||
* passed to the constructor, the system properties, the applet parameters,
|
||||
* passed to the constructor, the system properties,
|
||||
* and the application resource files. See
|
||||
* <a href=InitialContext.html#ENVIRONMENT><tt>InitialContext</tt></a>
|
||||
* for details.
|
||||
@ -268,8 +266,8 @@ import java.util.Hashtable;
|
||||
* <p>
|
||||
* In this way, each service provider developer can specify a list of
|
||||
* factories to use with that service provider. These can be modified by
|
||||
* the application resources specified by the deployer of the application
|
||||
* or applet, which in turn can be modified by the user.
|
||||
* the application resources specified by the deployer of the application,
|
||||
* which in turn can be modified by the user.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
* @author Scott Seligman
|
||||
@ -822,7 +820,7 @@ public interface Context {
|
||||
* of the property should be the fully qualified class name
|
||||
* of the factory class that will create an initial context.
|
||||
* This property may be specified in the environment parameter
|
||||
* passed to the initial context constructor, an applet parameter,
|
||||
* passed to the initial context constructor,
|
||||
* a system property, or an application resource file.
|
||||
* If it is not specified in any of these sources,
|
||||
* <tt>NoInitialContextException</tt> is thrown when an initial
|
||||
@ -837,7 +835,6 @@ public interface Context {
|
||||
* @see NoInitialContextException
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see #APPLET
|
||||
*/
|
||||
String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
|
||||
|
||||
@ -847,8 +844,8 @@ public interface Context {
|
||||
* of the property should be a colon-separated list of the fully
|
||||
* qualified class names of factory classes that will create an object
|
||||
* given information about the object.
|
||||
* This property may be specified in the environment, an applet
|
||||
* parameter, a system property, or one or more resource files.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or one or more resource files.
|
||||
*
|
||||
* <p> The value of this constant is "java.naming.factory.object".
|
||||
*
|
||||
@ -856,7 +853,6 @@ public interface Context {
|
||||
* @see javax.naming.spi.ObjectFactory
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see #APPLET
|
||||
*/
|
||||
String OBJECT_FACTORIES = "java.naming.factory.object";
|
||||
|
||||
@ -866,8 +862,8 @@ public interface Context {
|
||||
* of the property should be a colon-separated list of the fully
|
||||
* qualified class names of state factory classes that will be used
|
||||
* to get an object's state given the object itself.
|
||||
* This property may be specified in the environment, an applet
|
||||
* parameter, a system property, or one or more resource files.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or one or more resource files.
|
||||
*
|
||||
* <p> The value of this constant is "java.naming.factory.state".
|
||||
*
|
||||
@ -875,7 +871,6 @@ public interface Context {
|
||||
* @see javax.naming.spi.StateFactory
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see #APPLET
|
||||
* @since 1.3
|
||||
*/
|
||||
String STATE_FACTORIES = "java.naming.factory.state";
|
||||
@ -887,9 +882,8 @@ public interface Context {
|
||||
* of the property should be a colon-separated list of package
|
||||
* prefixes for the class name of the factory class that will create
|
||||
* a URL context factory.
|
||||
* This property may be specified in the environment,
|
||||
* an applet parameter, a system property, or one or more
|
||||
* resource files.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or one or more resource files.
|
||||
* The prefix <tt>com.sun.jndi.url</tt> is always appended to
|
||||
* the possibly empty list of package prefixes.
|
||||
*
|
||||
@ -900,7 +894,6 @@ public interface Context {
|
||||
* @see javax.naming.spi.ObjectFactory
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see #APPLET
|
||||
*/
|
||||
String URL_PKG_PREFIXES = "java.naming.factory.url.pkgs";
|
||||
|
||||
@ -909,8 +902,8 @@ public interface Context {
|
||||
* for specifying configuration information for the service provider
|
||||
* to use. The value of the property should contain a URL string
|
||||
* (e.g. "ldap://somehost:389").
|
||||
* This property may be specified in the environment,
|
||||
* an applet parameter, a system property, or a resource file.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or a resource file.
|
||||
* If it is not specified in any of these sources,
|
||||
* the default configuration is determined by the service provider.
|
||||
*
|
||||
@ -918,7 +911,6 @@ public interface Context {
|
||||
*
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see #APPLET
|
||||
*/
|
||||
String PROVIDER_URL = "java.naming.provider.url";
|
||||
|
||||
@ -926,8 +918,8 @@ public interface Context {
|
||||
* Constant that holds the name of the environment property
|
||||
* for specifying the DNS host and domain names to use for the
|
||||
* JNDI URL context (for example, "dns://somehost/wiz.com").
|
||||
* This property may be specified in the environment,
|
||||
* an applet parameter, a system property, or a resource file.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or a resource file.
|
||||
* If it is not specified in any of these sources
|
||||
* and the program attempts to use a JNDI URL containing a DNS name,
|
||||
* a <tt>ConfigurationException</tt> will be thrown.
|
||||
@ -1073,27 +1065,25 @@ public interface Context {
|
||||
String LANGUAGE = "java.naming.language";
|
||||
|
||||
/**
|
||||
* Constant that holds the name of the environment property for
|
||||
* specifying an applet for the initial context constructor to use
|
||||
* when searching for other properties.
|
||||
* The value of this property is the
|
||||
* <tt>java.applet.Applet</tt> instance that is being executed.
|
||||
* This property may be specified in the environment parameter
|
||||
* passed to the initial context constructor.
|
||||
* When this property is set, each property that the initial context
|
||||
* constructor looks for in the system properties is first looked for
|
||||
* in the applet's parameter list.
|
||||
* If this property is unspecified, the initial context constructor
|
||||
* will search for properties only in the environment parameter
|
||||
* passed to it, the system properties, and application resource files.
|
||||
* @deprecated An environment property with this name is ignored
|
||||
* while constructing an initial context.
|
||||
* This constant was originally used as a property name to specify an
|
||||
* {@code Applet} to retrieve parameters from, when creating an initial
|
||||
* context. Currently any applet properties that need to be passed to an
|
||||
* initial context should be copied into the environment hashtable:
|
||||
* <pre>{@code
|
||||
* Hashtable env = new Hashtable();
|
||||
* env.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
* ((Applet) this).getParameter(Context.INITIAL_CONTEXT_FACTORY));
|
||||
* env.put(Context.PROVIDER_URL,
|
||||
* ((Applet) this).getParameter(Context.PROVIDER_URL));
|
||||
* // ... other properties ...
|
||||
*
|
||||
* <p> The value of this constant is "java.naming.applet".
|
||||
*
|
||||
* @see #addToEnvironment(String, Object)
|
||||
* @see #removeFromEnvironment(String)
|
||||
* @see InitialContext
|
||||
* Context ctx = new InitialContext(env);
|
||||
* }</pre>
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
@Deprecated
|
||||
String APPLET = "java.naming.applet";
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,21 +41,13 @@ import com.sun.naming.internal.ResourceManager;
|
||||
* is initialized with properties defined in the environment parameter
|
||||
* passed to the constructor, and in any
|
||||
* <a href=Context.html#RESOURCEFILES>application resource files</a>.
|
||||
* In addition, a small number of standard JNDI properties may
|
||||
* be specified as system properties or as applet parameters
|
||||
* (through the use of {@link Context#APPLET}).
|
||||
* These special properties are listed in the field detail sections of the
|
||||
* <a href=Context.html#field_detail><tt>Context</tt></a> and
|
||||
* <a href=ldap/LdapContext.html#field_detail><tt>LdapContext</tt></a>
|
||||
* interface documentation.
|
||||
*<p>
|
||||
* JNDI determines each property's value by merging
|
||||
* the values from the following two sources, in order:
|
||||
* <ol>
|
||||
* <li>
|
||||
* The first occurrence of the property from the constructor's
|
||||
* environment parameter and (for appropriate properties) the applet
|
||||
* parameters and system properties.
|
||||
* environment parameter and system properties.
|
||||
* <li>
|
||||
* The application resource files (<tt>jndi.properties</tt>).
|
||||
* </ol>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -334,8 +334,8 @@ public interface LdapContext extends DirContext {
|
||||
* qualified class names of factory classes that will create a control
|
||||
* given another control. See
|
||||
* <tt>ControlFactory.getControlInstance()</tt> for details.
|
||||
* This property may be specified in the environment, an applet
|
||||
* parameter, a system property, or one or more resource files.
|
||||
* This property may be specified in the environment, a system property,
|
||||
* or one or more resource files.
|
||||
*<p>
|
||||
* The value of this constant is "java.naming.factory.control".
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -491,7 +491,7 @@ public class NamingManager {
|
||||
* (e.g. "ftpURLContextFactory" for the "ftp" scheme-id),
|
||||
* in the package specified as follows.
|
||||
* The <tt>Context.URL_PKG_PREFIXES</tt> environment property (which
|
||||
* may contain values taken from applet parameters, system properties,
|
||||
* may contain values taken from system properties,
|
||||
* or application resource files)
|
||||
* contains a colon-separated list of package prefixes.
|
||||
* Each package prefix in
|
||||
@ -661,8 +661,7 @@ public class NamingManager {
|
||||
if (className == null) {
|
||||
NoInitialContextException ne = new NoInitialContextException(
|
||||
"Need to specify class name in environment or system " +
|
||||
"property, or as an applet parameter, or in an " +
|
||||
"application resource file: " +
|
||||
"property, or in an application resource file: " +
|
||||
Context.INITIAL_CONTEXT_FACTORY);
|
||||
throw ne;
|
||||
}
|
||||
|
73
jdk/test/javax/naming/InitialContext/AppletIsNotUsed.java
Normal file
73
jdk/test/javax/naming/InitialContext/AppletIsNotUsed.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.NoInitialContextException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8051422
|
||||
* @summary Make sure java.applet.Applet is not used as a source of
|
||||
* configuration parameters for an InitialContext
|
||||
*/
|
||||
public class AppletIsNotUsed {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void main(String[] args) throws NamingException {
|
||||
|
||||
testWith(Context.APPLET);
|
||||
testWith("java.naming.applet");
|
||||
|
||||
}
|
||||
|
||||
private static void testWith(String appletProperty) throws NamingException {
|
||||
Hashtable<Object, Object> env = new Hashtable<>();
|
||||
// Deliberately put java.lang.Object rather than java.applet.Applet
|
||||
// if an applet was used we would see a ClassCastException down there
|
||||
env.put(appletProperty, new Object());
|
||||
// It's ok to instantiate InitialContext with no parameters
|
||||
// and be unaware of it right until you try to use it
|
||||
Context ctx = new InitialContext(env);
|
||||
boolean threw = true;
|
||||
try {
|
||||
ctx.lookup("whatever");
|
||||
threw = false;
|
||||
} catch (NoInitialContextException e) {
|
||||
String m = e.getMessage();
|
||||
if (m == null || m.contains("applet"))
|
||||
throw new RuntimeException("The exception message is incorrect", e);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(
|
||||
"The test was supposed to catch NoInitialContextException" +
|
||||
" here, but caught: " + t.getClass().getName(), t);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
if (!threw)
|
||||
throw new RuntimeException("The test was supposed to catch NoInitialContextException here");
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,12 +31,11 @@ import javax.naming.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class NoApplet {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void main(String[] args) throws NamingException {
|
||||
Hashtable<Object,Object> env = new Hashtable<>();
|
||||
env.put(Context.APPLET, new Object());
|
||||
try {
|
||||
Context ctxt = new InitialContext(env);
|
||||
throw new RuntimeException("ClassCastException expected");
|
||||
} catch (ClassCastException expected) { }
|
||||
ctxt.close();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user