Skip to content

Commit 4338f52

Browse files
committed
8294241: Deprecate URL public constructors
Reviewed-by: joehw, prr, alanb, aefimov, michaelm
1 parent 68209ad commit 4338f52

82 files changed

Lines changed: 848 additions & 146 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/java.base/share/classes/java/io/File.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,9 @@ public URL toURL() throws MalformedURLException {
694694
if (isInvalid()) {
695695
throw new MalformedURLException("Invalid file path");
696696
}
697-
return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
697+
@SuppressWarnings("deprecation")
698+
var result = new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
699+
return result;
698700
}
699701

700702
/**

src/java.base/share/classes/java/net/HttpConnectSocketImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -184,6 +184,7 @@ private Socket doTunnel(String urlString, int connectTimeout)
184184
throws IOException
185185
{
186186
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
187+
@SuppressWarnings("deprecation")
187188
URL destURL = new URL(urlString);
188189
HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
189190
conn.setConnectTimeout(connectTimeout);

src/java.base/share/classes/java/net/JarURLConnection.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -172,14 +172,17 @@ private void parseSpecs(URL url) throws MalformedURLException {
172172
throw new MalformedURLException("no !/ found in url spec:" + spec);
173173
}
174174

175-
jarFileURL = new URL(spec.substring(0, separator++));
175+
@SuppressWarnings("deprecation")
176+
var _unused = jarFileURL = new URL(spec.substring(0, separator++));
177+
176178
/*
177179
* The url argument may have had a runtime fragment appended, so
178180
* we need to add a runtime fragment to the jarFileURL to enable
179181
* runtime versioning when the underlying jar file is opened.
180182
*/
181183
if ("runtime".equals(url.getRef())) {
182-
jarFileURL = new URL(jarFileURL, "#runtime");
184+
@SuppressWarnings("deprecation")
185+
var _unused2 = jarFileURL = new URL(jarFileURL, "#runtime");
183186
}
184187
entryName = null;
185188

src/java.base/share/classes/java/net/URI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ public URI relativize(URI uri) {
11331133
* or if some other error occurred while constructing the URL
11341134
*/
11351135
public URL toURL() throws MalformedURLException {
1136-
return URL.fromURI(this);
1136+
return URL.of(this, null);
11371137
}
11381138

11391139
// -- Component access methods --

src/java.base/share/classes/java/net/URL.java

Lines changed: 125 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,26 @@
129129
* the protocol, host name, or port number is missing, the value is
130130
* inherited from the fully specified URL. The file component must be
131131
* specified. The optional fragment is not inherited.
132+
*
133+
* <h2><a id="constructor-deprecation"></a>Constructing instances of {@code URL}</h2>
134+
*
135+
* The {@code java.net.URL} constructors are deprecated.
136+
* Developers are encouraged to use {@link URI java.net.URI} to parse
137+
* or construct a {@code URL}. In cases where an instance of {@code
138+
* java.net.URL} is needed to open a connection, {@link URI} can be used
139+
* to construct or parse the URL string, possibly calling {@link
140+
* URI#parseServerAuthority()} to validate that the authority component
141+
* can be parsed as a server-based authority, and then calling
142+
* {@link URI#toURL()} to create the {@code URL} instance.
143+
* <p>
144+
* The URL constructors are specified to throw
145+
* {@link MalformedURLException} but the actual parsing/validation
146+
* that is performed is implementation dependent. Some parsing/validation
147+
* may be delayed until later, when the underlying {@linkplain
148+
* URLStreamHandler stream handler's implementation} is called.
149+
* Being able to construct an instance of {@code URL} doesn't
150+
* provide any guarantee about its conformance to the URL
151+
* syntax specification.
132152
* <p>
133153
* The URL class does not itself encode or decode any URL components
134154
* according to the escaping mechanism defined in RFC2396. It is the
@@ -152,6 +172,7 @@
152172
*
153173
* @apiNote
154174
*
175+
* <a id="integrity"></a>
155176
* Applications working with file paths and file URIs should take great
156177
* care to use the appropriate methods to convert between the two.
157178
* The {@link Path#of(URI)} factory method and the {@link File#File(URI)}
@@ -164,6 +185,11 @@
164185
* from the direct string representation of a {@code File} or {@code Path}
165186
* instance.
166187
* <p>
188+
* Before constructing a {@code URL} from a {@code URI}, and depending
189+
* on the protocol involved, applications should consider validating
190+
* whether the URI authority {@linkplain URI#parseServerAuthority()
191+
* can be parsed as server-based}.
192+
* <p>
167193
* Some components of a URL or URI, such as <i>userinfo</i>, may
168194
* be abused to construct misleading URLs or URIs. Applications
169195
* that deal with URLs or URIs should take into account
@@ -373,7 +399,11 @@ public final class URL implements java.io.Serializable {
373399
* @see java.net.URLStreamHandler
374400
* @see java.net.URLStreamHandlerFactory#createURLStreamHandler(
375401
* java.lang.String)
402+
* @deprecated Use {@link URI#toURL()} to construct an instance of URL. See the note on
403+
* <a href="#constructor-deprecation">constructor deprecation</a> for more
404+
* details.
376405
*/
406+
@Deprecated(since = "20")
377407
public URL(String protocol, String host, int port, String file)
378408
throws MalformedURLException
379409
{
@@ -399,7 +429,11 @@ public URL(String protocol, String host, int port, String file)
399429
* rejects, or is known to reject, the {@code URL}
400430
* @see java.net.URL#URL(java.lang.String, java.lang.String,
401431
* int, java.lang.String)
432+
* @deprecated Use {@link URI#toURL()} to construct an instance of URL. See the note on
433+
* <a href="#constructor-deprecation">constructor deprecation</a> for more
434+
* details.
402435
*/
436+
@Deprecated(since = "20")
403437
public URL(String protocol, String host, String file)
404438
throws MalformedURLException {
405439
this(protocol, host, -1, file);
@@ -446,7 +480,13 @@ public URL(String protocol, String host, String file)
446480
* java.lang.String)
447481
* @see SecurityManager#checkPermission
448482
* @see java.net.NetPermission
483+
* @deprecated
484+
* Use {@link #of(URI, URLStreamHandler)} to construct an instance of URL
485+
* associated with a custom protocol handler.
486+
* See the note on <a href="#constructor-deprecation">constructor deprecation</a>
487+
* for more details.
449488
*/
489+
@Deprecated(since = "20")
450490
public URL(String protocol, String host, int port, String file,
451491
URLStreamHandler handler) throws MalformedURLException {
452492
if (handler != null) {
@@ -533,7 +573,11 @@ public URL(String protocol, String host, int port, String file,
533573
* URLStreamHandler#parseURL parseURL method} throws
534574
* {@code IllegalArgumentException}
535575
* @see java.net.URL#URL(java.net.URL, java.lang.String)
576+
* @deprecated Use {@link URI#toURL()} to construct an instance of URL. See the note on
577+
* <a href="#constructor-deprecation">constructor deprecation</a> for more
578+
* details.
536579
*/
580+
@Deprecated(since = "20")
537581
public URL(String spec) throws MalformedURLException {
538582
this(null, spec);
539583
}
@@ -593,7 +637,11 @@ public URL(String spec) throws MalformedURLException {
593637
* @see java.net.URLStreamHandler
594638
* @see java.net.URLStreamHandler#parseURL(java.net.URL,
595639
* java.lang.String, int, int)
640+
* @deprecated Use {@link URI#toURL()} to construct an instance of URL. See the note on
641+
* <a href="#constructor-deprecation">constructor deprecation</a> for more
642+
* details.
596643
*/
644+
@Deprecated(since = "20")
597645
public URL(URL context, String spec) throws MalformedURLException {
598646
this(context, spec, null);
599647
}
@@ -626,7 +674,13 @@ public URL(URL context, String spec) throws MalformedURLException {
626674
* @see java.net.URLStreamHandler
627675
* @see java.net.URLStreamHandler#parseURL(java.net.URL,
628676
* java.lang.String, int, int)
677+
* @deprecated
678+
* Use {@link #of(URI, URLStreamHandler)} to construct an instance of URL
679+
* associated with a custom protocol handler.
680+
* See the note on <a href="#constructor-deprecation">constructor deprecation</a>
681+
* for more details.
629682
*/
683+
@Deprecated(since = "20")
630684
public URL(URL context, String spec, URLStreamHandler handler)
631685
throws MalformedURLException
632686
{
@@ -748,23 +802,70 @@ public URL(URL context, String spec, URLStreamHandler handler)
748802
}
749803

750804
/**
751-
* Creates a URL from a URI, as if by invoking {@code uri.toURL()}.
805+
* Creates a URL from a URI, as if by invoking {@code uri.toURL()}, but
806+
* associating it with the given {@code URLStreamHandler}, if allowed.
807+
*
808+
* @apiNote
809+
* Applications should consider performing additional integrity
810+
* checks before constructing a {@code URL} and opening a connection.
811+
* See the <a href=#integrity>API note</a> in the class level API
812+
* documentation.
813+
*
814+
* @implSpec The implementation of this method includes calling the {@link
815+
* URLStreamHandler#parseURL(URL, String, int, int) parseURL} method on the
816+
* selected handler.
817+
*
818+
* @param uri the {@code URI} from which the returned {@code URL} should
819+
* be built
820+
* @param handler a custom protocol stream handler for
821+
* the returned {@code URL}. Can be {@code null},
822+
* in which case the default stream handler for
823+
* the protocol if any, will be used.
824+
*
825+
* @return a new {@code URL} instance created from the given {@code URI}
826+
* and associated with the given {@code URLStreamHandler}, if any
827+
*
828+
* @throws NullPointerException if {@code uri} is {@code null}
829+
*
830+
* @throws IllegalArgumentException if no protocol is specified
831+
* (the {@linkplain URI#getScheme() uri scheme} is {@code null}), or
832+
* if the {@code URLStreamHandler} is not {@code null} and can not be
833+
* set for the given protocol
834+
*
835+
* @throws MalformedURLException if an unknown protocol is found,
836+
* or the given URI fails to comply with the specific
837+
* syntax of the associated protocol, or the
838+
* underlying stream handler's {@linkplain
839+
* URLStreamHandler#parseURL(URL, String, int, int)
840+
* parseURL method} throws {@code IllegalArgumentException}
841+
*
842+
* @throws SecurityException
843+
* if a security manager exists and its
844+
* {@code checkPermission} method doesn't allow
845+
* specifying a stream handler
752846
*
753847
* @see java.net.URI#toURL()
848+
*
849+
* @since 20
754850
*/
755-
static URL fromURI(URI uri) throws MalformedURLException {
851+
public static URL of(URI uri, URLStreamHandler handler)
852+
throws MalformedURLException {
756853
if (!uri.isAbsolute()) {
757854
throw new IllegalArgumentException("URI is not absolute");
758855
}
856+
759857
String protocol = uri.getScheme();
760858

859+
// fast path for canonical jrt:/... URLs
860+
//
761861
// In general we need to go via Handler.parseURL, but for the jrt
762862
// protocol we enforce that the Handler is not overridable and can
763863
// optimize URI to URL conversion.
764864
//
765865
// Case-sensitive comparison for performance; malformed protocols will
766866
// be handled correctly by the slow path.
767-
if (protocol.equals("jrt") && !uri.isOpaque()
867+
if (handler == null && protocol.equals("jrt") && !uri.isOpaque()
868+
&& uri.getRawAuthority() == null
768869
&& uri.getRawFragment() == null) {
769870

770871
String query = uri.getRawQuery();
@@ -780,9 +881,28 @@ static URL fromURI(URI uri) throws MalformedURLException {
780881
int port = uri.getPort();
781882

782883
return new URL("jrt", host, port, file, null);
783-
} else {
784-
return new URL((URL)null, uri.toString(), null);
785884
}
885+
886+
// slow path (will work for non-canonical forms of jrt: too)
887+
888+
if ("url".equalsIgnoreCase(protocol)) {;
889+
String uristr = uri.toString();
890+
try {
891+
URI inner = new URI(uristr.substring(4));
892+
if (inner.isAbsolute()) {
893+
protocol = inner.getScheme();
894+
}
895+
} catch (URISyntaxException use) {
896+
throw new MalformedURLException(use.getMessage());
897+
}
898+
}
899+
900+
if (handler != null && !isOverrideable(protocol)) {
901+
throw new IllegalArgumentException("Can't override URLStreamHandler for protocol "
902+
+ protocol);
903+
}
904+
905+
return new URL((URL)null, uri.toString(), handler);
786906
}
787907

788908
/*

src/java.base/share/classes/java/security/Security.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
package java.security;
2727

28+
import java.net.MalformedURLException;
2829
import java.util.*;
2930
import java.util.concurrent.ConcurrentHashMap;
3031
import java.io.*;
@@ -135,10 +136,10 @@ private static boolean loadProps(File masterFile, String extraPropFile, boolean
135136
File propFile = new File(extraPropFile);
136137
URL propURL;
137138
if (propFile.exists()) {
138-
propURL = new URL
139+
propURL = newURL
139140
("file:" + propFile.getCanonicalPath());
140141
} else {
141-
propURL = new URL(extraPropFile);
142+
propURL = newURL(extraPropFile);
142143
}
143144

144145
is = propURL.openStream();
@@ -993,4 +994,9 @@ public static Set<String> getAlgorithms(String serviceName) {
993994
}
994995
return Collections.unmodifiableSet(result);
995996
}
997+
998+
@SuppressWarnings("deprecation")
999+
private static URL newURL(String spec) throws MalformedURLException {
1000+
return new URL(spec);
1001+
}
9961002
}

src/java.base/share/classes/javax/crypto/JceSecurity.java.template

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -243,7 +243,8 @@ final class JceSecurity {
243243

244244
static {
245245
try {
246-
NULL_URL = new URL("http://null.oracle.com/");
246+
@SuppressWarnings("deprecation")
247+
var _unused = NULL_URL = new URL("http://null.oracle.com/");
247248
} catch (Exception e) {
248249
throw new RuntimeException(e);
249250
}

src/java.base/share/classes/javax/crypto/ProviderVerifier.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ void verify() throws IOException {
9191
// If the protocol of jarURL isn't "jar", we should
9292
// construct a JAR URL so we can open a JarURLConnection
9393
// for verifying this provider.
94+
@SuppressWarnings("deprecation")
9495
final URL url = jarURL.getProtocol().equalsIgnoreCase("jar")?
9596
jarURL : new URL("jar:" + jarURL + "!/");
9697

0 commit comments

Comments
 (0)