author | lancea |
Wed, 11 Jul 2018 19:36:23 -0400 | |
branch | JDK-8188051-branch |
changeset 56828 | 64304e37e9b1 |
parent 56824 | 62e92191354d |
child 56832 | 4f7713e6a308 |
permissions | -rw-r--r-- |
56380 | 1 |
/* |
56475 | 2 |
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. |
56380 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
||
27 |
/** |
|
28 |
* <p> |
|
29 |
* An API for accessing and processing data stored in a data source (usually a |
|
30 |
* relational database) using the Java™ programming language. This API |
|
31 |
* includes a framework whereby different drivers can be installed dynamically |
|
32 |
* to access different data sources. This API is specifically geared for passing |
|
33 |
* SQL statements to a database though it may be used for reading and writing |
|
34 |
* data from/to any data source that has a tabular format.</p> |
|
35 |
* |
|
36 |
* <p> |
|
37 |
* This API differs from the API in {@code java.sql} in several ways.</p> |
|
38 |
* <ul> |
|
39 |
* <li>Is asynchronous |
|
40 |
* <li>Is geared toward high-throughput programs |
|
41 |
* <li>Does not attempt to support every database feature |
|
42 |
* <li>Does not attempt to abstract the database |
|
43 |
* <li>Uses the builder pattern |
|
44 |
* <li>Supports the fluent programming style |
|
45 |
* </ul> |
|
46 |
* |
|
47 |
* <p> |
|
48 |
* It is worth emphasizing that this API is an alternate to the {@code java.sql} |
|
49 |
* API, not a replacement. There are many programs that can much more readily be |
|
50 |
* written using the {@code java.sql} API as it has many features that are not |
|
51 |
* available in this API. For example this API provides almost no mechanism for |
|
52 |
* getting metadata.</p> |
|
53 |
* |
|
54 |
* <p> |
|
55 |
* This API is not an extension to the {@code java.sql} API. It an independent |
|
56 |
* API and is used on its own without reference to java.sql. </p> |
|
57 |
* |
|
58 |
* |
|
59 |
* <h3>Overview</h3> |
|
60 |
* |
|
61 |
* <p> |
|
62 |
* The core feature of this API is that it is asynchronous. No method call will |
|
63 |
* wait for a network operation. </p> |
|
64 |
* |
|
65 |
* <p> |
|
66 |
* Possibly blocking actions are represented as {@link Operation}s. An |
|
67 |
* application using the API creates and submits one or more {@link Operation}s. |
|
56475 | 68 |
* The implementation executes these {@link Operation}s asynchronously, reporting |
69 |
* their results via {@link java.util.concurrent.CompletionStage}s. An application |
|
56380 | 70 |
* can respond to the results via the |
71 |
* {@link java.util.concurrent.CompletionStage}s or via callbacks that can be |
|
72 |
* configured on many of the {@link Operation}s or both. Creating and submitting |
|
73 |
* {@link Operation}s is strictly non-blocking. Handling the results of possibly |
|
74 |
* blocking {@link Operation}s is done asynchronously. No application thread |
|
75 |
* will ever block on a call to a method in this API.</p> |
|
76 |
* |
|
77 |
* <p> |
|
78 |
* All {@link Operation}s provide a |
|
79 |
* {@link java.util.concurrent.CompletionStage}. The value of that |
|
80 |
* {@link java.util.concurrent.CompletionStage} is the value of the |
|
81 |
* {@link Operation}, set when the {@link Operation} completes. Some |
|
82 |
* {@link Operation}s provide callbacks for processing the result of the |
|
83 |
* {@link Operation} independent of the |
|
84 |
* {@link java.util.concurrent.CompletionStage}. Those {@link Operation}s can |
|
85 |
* be used for executing SQL that returns results of a specific type. For |
|
86 |
* example SQL that returns a row sequence would be executed with a |
|
87 |
* {@link RowOperation}. A {@link RowOperation} provides callbacks for |
|
88 |
* processing each row and for collecting the results of processing the rows. |
|
89 |
* Other {@link Operation}s are specialized for SQL that returns a count or that |
|
90 |
* returns out parameters. The choice of {@link Operation} is dependent on the |
|
91 |
* result to be processed and is independent of the particular kind of SQL |
|
92 |
* statement.</p> |
|
93 |
* |
|
94 |
* <p> |
|
95 |
* An {@link OperationGroup} encapsulates a group of {@link Operation}s and |
|
96 |
* executes them using common attributes. An {@link OperationGroup} can be |
|
97 |
* unconditional or conditional, sequential or parallel, dependent or |
|
98 |
* independent, or any combination of these. Dependent/independent controls |
|
99 |
* error handling. If one member of a dependent {@link OperationGroup} fails the |
|
100 |
* remaining not-yet-executed members are completed exceptionally. If the |
|
101 |
* {@link OperationGroup} is independent, the member {@link Operation}s are |
|
102 |
* executed regardless of whether one or more fails.</p> |
|
103 |
* |
|
104 |
* <p> |
|
56824 | 105 |
* A single context in a data source is represented by a {@link Session}. A |
106 |
* {@link Session} is somewhat analogous to a logical {@link java.sql.Connection}. |
|
107 |
* A physical {@link java.sql.Connection} has no representation in this API; if |
|
108 |
* such an entity exists at all it is strictly internal to an implementation. |
|
109 |
* Within this spec this entity is referred to as a "data source resource". |
|
110 |
* </p> |
|
111 |
* |
|
112 |
* <p> |
|
113 |
* A {@link Session} is itself an {@link OperationGroup} and so can be |
|
56380 | 114 |
* conditional, parallel, or independent, but by default is unconditional, |
56824 | 115 |
* sequential, dependent. While a {@link Session} may be created with values |
56380 | 116 |
* other than the defaults, using the defaults is by far the most common case. |
117 |
* The API provides convenience methods that support this case. Using these |
|
118 |
* convenience methods is recommended in all but the most unusual circumstances. |
|
56824 | 119 |
* In particular making the {@link Session} parallel introduces some |
56380 | 120 |
* challenges that would require a full understanding of the details of the API. |
121 |
* It would almost certainly be better to create a parallel |
|
56824 | 122 |
* {@link OperationGroup} within the {@link Session}.</p> |
56380 | 123 |
* |
124 |
* <p> |
|
125 |
* <i> |
|
56824 | 126 |
* ISSUE: Should we disallow {@code Session.parallel()}?</i></p> |
56380 | 127 |
* |
128 |
* <p> |
|
129 |
* The {@code java.sql} API frequently provides many ways to do the same thing. |
|
130 |
* This API makes no attempt to do this. For those capabilities this API |
|
131 |
* supports, it frequently defines exactly one way to do something. Doing things |
|
132 |
* another way, for example calling methods in a non-standard order, frequently |
|
133 |
* results in an IllegalStateException. This approach is intended to make things |
|
134 |
* simpler for both the user and the implementor. Rather than having to |
|
135 |
* understand complicated interactions of many different components and methods |
|
136 |
* executed in any order, the intent is that there is only one way to do things |
|
137 |
* so only one path must be understood or implemented. Anything off that path is |
|
138 |
* an error. While this requires a programmer to write code in one specific way |
|
139 |
* it makes things easier on future maintainers of the code as the code will |
|
140 |
* conform to the standard pattern. Similarly the implementation is simplified |
|
141 |
* as only the standard use pattern is supported.</p> |
|
142 |
* |
|
143 |
* <p> |
|
144 |
* One way this API simplifies things in to define types as single use. Many |
|
56475 | 145 |
* types are created, configured, used once, and are then no longer usable. Most |
56380 | 146 |
* configuration methods can be called only once on a given instance. Once an |
147 |
* instance is configured it cannot be reconfigured. Once an instance is used it |
|
148 |
* cannot be reused. This simplifies things by eliminating the need to |
|
149 |
* understand and implement arbitrary sequences of method calls that reconfigure |
|
150 |
* and reuse instances. Since objects are single use there is no expectation |
|
151 |
* that an application cache or share {@link Operation}s.</p> |
|
152 |
* |
|
153 |
* <p> |
|
154 |
* While the user visible types are single use, it is expected that an |
|
155 |
* implementation will cache and reuse data and {@link Object}s that are worth |
|
156 |
* the effort. Rather than attempt to guess what an implementation should reuse |
|
157 |
* and capture that in the API, this API leaves it entirely up to the |
|
158 |
* implementation. Since the API specifies very little reuse, an implementation |
|
159 |
* is free to reuse whatever is appropriate. Since the pattern of use is |
|
160 |
* strictly enforced figuring out how to reuse objects is greatly |
|
161 |
* simplified.</p> |
|
162 |
* |
|
163 |
* <p> |
|
164 |
* The {@code java.sql} API provides many tools for abstracting the database, |
|
165 |
* for enabling the user to write database independent code. This API does not. |
|
166 |
* It is not a goal of this API to enable users to write database independent |
|
167 |
* code. That is not to say it is not possible, just that this API does not |
|
168 |
* provide tools to support such. Abstraction features typically impose |
|
169 |
* performance penalties on some implementations. As this API is geared for |
|
170 |
* high-throughput programs it avoids such abstractions rather than reduce |
|
171 |
* performance.</p> |
|
172 |
* |
|
173 |
* <p> |
|
174 |
* One such abstraction feature is the JDBC escape sequences. Implementing these |
|
175 |
* features requires parsing the SQL so as to identify the escape sequences and |
|
176 |
* then generating a new String with the vendor specific SQL corresponding to |
|
177 |
* the escape sequence. This is an expensive operation. Further each SQL must be |
|
178 |
* parsed whether it contains an escape sequence or not imposing the cost on all |
|
179 |
* JDBC users, not just the ones who use escape sequences. The same is true of |
|
180 |
* JDBC parameter markers. The SQL accepted by this API is entirely vendor |
|
181 |
* specific, including parameter markers. There is no need for pre-processing |
|
182 |
* prior to SQL execution substantially reducing the amount of work the |
|
183 |
* implementation must do.</p> |
|
184 |
* |
|
185 |
* <p> |
|
186 |
* Note: It would be a reasonable future project to develop a SQL builder API |
|
187 |
* that creates vendor specific SQL from some more abstract representation.</p> |
|
56475 | 188 |
* |
189 |
* <p> |
|
190 |
* This API is targeted at high-throughput apps. If a particular feature of this |
|
191 |
* API would have a surprising performance impact for a particular implementation |
|
192 |
* it is recommended that the implementation not implement that feature. It is |
|
193 |
* better that a feature be unsupported as opposed to users investing substantial |
|
194 |
* effort in an app using that feature only to discover in production that the |
|
195 |
* performance is unacceptable. For example, if an implementation can only support |
|
196 |
* {@link Operation#timeout} through active polling it would be better for that |
|
56797 | 197 |
* implementation to throw {@link UnsupportedOperationException} if |
56824 | 198 |
* {@link Operation#timeout} is called. To this end every type and method is |
199 |
* optional except returning a {@link DataSourceFactory} in response to a call to |
|
200 |
* {@link DataSourceFactory#newFactory} with the appropriate name.</p> |
|
56380 | 201 |
* |
202 |
* <h3>Execution Model</h3> |
|
203 |
* |
|
204 |
* <p> |
|
205 |
* <i>This section describes the function of a conforming implementation. It is |
|
206 |
* not necessary for an implementation to be implemented as described only that |
|
207 |
* the behavior be the same.</i></p> |
|
208 |
* |
|
209 |
* <p> |
|
210 |
* An {@link Operation} has an action and a |
|
211 |
* {@link java.util.concurrent.CompletionStage}. Some {@link Operation}s have |
|
212 |
* some form of result processor.</p> |
|
213 |
* |
|
214 |
* <p> |
|
215 |
* An {@link Operation} is executed by causing the action to be performed, |
|
216 |
* processing the result of the action if there is a result processor, and |
|
217 |
* completing the {@link java.util.concurrent.CompletionStage} with the result |
|
56824 | 218 |
* of the result processor if there is one. If the action or the result processing |
219 |
* causes an unhandled error the {@link java.util.concurrent.CompletionStage} is |
|
56797 | 220 |
* completed exceptionally. The {@link java.util.concurrent.CompletionStage} is |
221 |
* completed asynchronously, as though it were created by calling an |
|
222 |
* <i>async</i> method on {@link java.util.concurrent.CompletionStage}. |
|
56380 | 223 |
* </p> |
224 |
* |
|
225 |
* <p> |
|
226 |
* Performing the action may require one or more interactions with the database. |
|
227 |
* These interactions may be carried out in parallel with processing the result. |
|
56824 | 228 |
* If the database result is ordered, that result is processed in the order |
229 |
* specified by the database.</p> |
|
56380 | 230 |
* |
231 |
* <p> |
|
56824 | 232 |
* An {@link OperationGroup} has a collection of member {@link Operation}s and |
56380 | 233 |
* optionally a condition. For a sequential {@link OperationGroup} |
234 |
* {@link Operation}s are selected from the collection in the order they were |
|
235 |
* submitted. For a parallel {@link OperationGroup} {@link Operation}s are |
|
236 |
* selected from the collection in any order.</p> |
|
237 |
* |
|
238 |
* <p> |
|
239 |
* The action of an {@link OperationGroup} is performed as follows: |
|
240 |
* <ul> |
|
241 |
* <li> |
|
242 |
* If the {@link OperationGroup} has a condition, the value of the condition is |
|
243 |
* retrieved. If the value is {@link Boolean#FALSE} the action is complete and |
|
244 |
* the {@link java.util.concurrent.CompletionStage} is completed with null. If |
|
56797 | 245 |
* the condition value completes exceptionally the action is complete and the |
56380 | 246 |
* {@link java.util.concurrent.CompletionStage} is completed exceptionally |
247 |
* with the same exception. If the condition value is {@link Boolean#TRUE} or |
|
248 |
* there is no condition the {@link Operation}s in the collection are executed |
|
249 |
* and their results processed. The action is complete when the |
|
250 |
* {@link OperationGroup} is not held and all the {@link Operation}s have been |
|
251 |
* executed.</li> |
|
252 |
* <li> |
|
56797 | 253 |
* If the {@link OperationGroup} is parallel more than one member |
254 |
* {@link Operation} may be executed at a time.</li> |
|
56380 | 255 |
* <li> |
56797 | 256 |
* If the {@link OperationGroup} is dependent and a member {@link Operation} completes |
257 |
* exceptionally all member {@link Operation}s that are yet to begin |
|
56380 | 258 |
* execution are completed exceptionally with a {@link SqlSkippedException}. The |
259 |
* cause of that exception is the {@link Throwable} that caused the |
|
260 |
* {@link Operation} to be completed exceptionally. If an {@link Operation} is |
|
261 |
* in flight when another {@link Operation} completes exceptionally the in |
|
262 |
* flight {@link Operation} may either be allowed to complete uninterrupted or |
|
56797 | 263 |
* it may be completed exceptionally. The {@link OperationGroup} is dependent it |
264 |
* is completed exceptionally with the {@link Throwable} that caused the |
|
265 |
* {@link Operation} to complete exceptionally. |
|
56475 | 266 |
* |
267 |
* <p> |
|
56824 | 268 |
* Note: the {@link Operation}s returned by {@link Session#closeOperation} |
56479 | 269 |
* and {@link OperationGroup#catchOperation} are never skipped, i.e. never |
56475 | 270 |
* completed exceptionally with {@link SqlSkippedException}. The {@link Operation} |
271 |
* returned by {@link OperationGroup#catchOperation} never completes |
|
56797 | 272 |
* exceptionally so the following {@link Operation} is always executed normally. |
56475 | 273 |
* No {@link Operation} can be submitted after the {@link Operation} returned by |
56824 | 274 |
* {@link Session#closeOperation} has been submitted.</p> </li> |
56380 | 275 |
* <li> |
276 |
* If the {@link OperationGroup} is independent and an {@link Operation} |
|
277 |
* completes exceptionally all other {@link Operation}s are executed regardless. |
|
278 |
* There is no result to be processed for an {@link Operation} that completed |
|
279 |
* exceptionally. The {@link OperationGroup} is not completed exceptionally as |
|
280 |
* the result of one or more {@link Operation}s completing exceptionally.</li> |
|
281 |
* </ul> |
|
282 |
* |
|
283 |
* <p> |
|
56824 | 284 |
* A {@link Session} is a distinguished {@link OperationGroup}. A |
285 |
* {@link Session} is executed upon being submitted.</p> |
|
56380 | 286 |
* |
287 |
* <h3>Transactions</h3> |
|
288 |
* |
|
289 |
* <p> |
|
290 |
* <i>This section describes the function of a conforming implementation. It is |
|
291 |
* not necessary for an implementation to be implemented as described only that |
|
292 |
* the behavior be the same.</i></p> |
|
293 |
* |
|
294 |
* <p> |
|
295 |
* An implementation has only limited control over transactions. SQL statements |
|
296 |
* can start, commit, and rollback transactions without the implementation |
|
297 |
* having any influence or even being aware. This specification only describes |
|
298 |
* the behavior of those transaction actions that are visible to and controlled |
|
299 |
* by the implementation, i.e. the endTransaction {@link Operation}. |
|
300 |
* Transaction actions caused by SQL may interact with actions controlled by the |
|
301 |
* implementation in unexpected ways.</p> |
|
302 |
* |
|
303 |
* <p> |
|
304 |
* The creation of Operations and the subsequent execution of those Operations |
|
305 |
* are separated in time. It is quite reasonable to determine that a transaction |
|
56824 | 306 |
* should commit after the Operation that ends the transaction is submitted. But |
307 |
* if the execution of the transaction does not result in the expected results |
|
56380 | 308 |
* it might be necessary to rollback the transaction rather than commit it. This |
309 |
* determination depends on the execution of the Operations long after the |
|
56824 | 310 |
* endTransaction Operation is submitted. To address this mismatch, the |
56828
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
311 |
* endTransaction Operation is conditioned by a {@link TransactionCompletion}. By |
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
312 |
* default, a {@link TransactionCompletion} will cause an endTransaciton |
56824 | 313 |
* {@link Operation} to commit the transaction. At any time before the |
314 |
* endTransaction {@link Operation} that references it is executed a |
|
56828
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
315 |
* {@link TransactionCompletion} can be set to rollback the transaction .</p> |
56380 | 316 |
* |
317 |
* <p> |
|
56824 | 318 |
* An endTransaction {@link Operation}, like all {@link Operation}s, is |
319 |
* immutable once submitted. But an endTransaction {@link Operation} is created |
|
56828
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
320 |
* with a {@link TransactionCompletion} and that {@link TransactionCompletion} can be set to |
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
321 |
* commit or rollback. A {@link TransactionCompletion} controls the endTransaction |
56824 | 322 |
* {@link Operation} created with it. Using this mechanism an error handler, |
323 |
* result handler or other code can cause a subsequent endTransaction |
|
56475 | 324 |
* {@link Operation} to rollback instead of the default which is to commit.</p> |
56380 | 325 |
* |
326 |
* <pre> |
|
327 |
* {@code |
|
56828
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
328 |
* TransactionCompletion t = session.getTransactionEnd(); |
56824 | 329 |
* session.countOperation(updateSql) |
56380 | 330 |
* .resultProcessor( count -> { |
331 |
* if (count > 1) t.setRollbackOnly(); |
|
332 |
* return null; |
|
333 |
* } ) |
|
334 |
* .submit(); |
|
56824 | 335 |
* session.catchErrors(); |
336 |
* session.commitMaybeRollback(t); |
|
56380 | 337 |
* } |
338 |
* </pre> |
|
339 |
* |
|
340 |
* <p> |
|
341 |
* In this example if the update SQL modifies more than one row the result |
|
56828
64304e37e9b1
JDK-8188051-branch javadoc updates and added TransactionCompletion.java
lancea
parents:
56824
diff
changeset
|
342 |
* processor will set the {@link TransactionCompletion} to rollback only. When the |
56824 | 343 |
* endTransaction {@link Operation} submitted by |
344 |
* {@link OperationGroup#commitMaybeRollback} is executed it will cause the |
|
345 |
* transaction to rollback.</p> |
|
346 |
* |
|
56380 | 347 |
* |
56797 | 348 |
* <h3>Implementation Note</h3> |
349 |
* |
|
350 |
* <p> |
|
351 |
* If an implementation exposes any implementation specific types and methods, the |
|
352 |
* implementation is expected to provide covariant overrides for all methods that |
|
353 |
* return the standard super-type of the implementation specific type.</p> |
|
354 |
* |
|
355 |
* <p> |
|
356 |
* Consider an implementation that adds a method foo() to RowCountOperation. To do |
|
357 |
* that it would have to expose a type FooRowCountOperation extends RowCountOperation. |
|
358 |
* So that an application can transparently access foo, the implementation would |
|
56824 | 359 |
* also have to expose FooDataSource, FooOperationGroup and FooSession. Further |
56797 | 360 |
* each of these types would have to declare covariant overrides for every method |
361 |
* that returns a direct super-type of one of these types.</p> |
|
362 |
* <ul> |
|
363 |
* <li>FooDataSourceFactory must override builder to return FooDataSource.Builder</li> |
|
364 |
* <li>FooDataSource.Builder must override url, password, etc to return a |
|
365 |
* FooDataSource.Builder. build must return a FooDataSource.</li> |
|
56824 | 366 |
* <li>FooDataSource must override builder to return FooSession.Builder</li> |
367 |
* <li>FooSession.Builder must override url, password, etc to return a |
|
368 |
* FooSession.Builder. build must return a FooSession</li> |
|
369 |
* <li>FooDataSource must override getSession to return FooSession</li> |
|
370 |
* <li>FooSession must extend FooOperationGroup</li> |
|
56797 | 371 |
* <li>FooOperationGroup> must override rowCountOperation to return FooRowCountOperation</li> |
372 |
* <li>FooRowCountOperation must override apply and onError to return FooRowCountOperation</li> |
|
373 |
* </ul> |
|
374 |
* <p> |
|
375 |
* The intent is to transparently expose the vendor extension without use of casts. |
|
376 |
* Example: </p> |
|
377 |
* |
|
378 |
* <pre> |
|
379 |
* {@code |
|
380 |
* FooDataSourceFactory factory = DataSourceFatory.newFactory("com.foo.FooDataSourceFatory"); |
|
381 |
* FooDataSource dataSource = factory.builder() |
|
382 |
* .url("scott/tiger@host:port") |
|
383 |
* .build(); |
|
56824 | 384 |
* FooSession session = dataSource.getSession(); |
385 |
* CompletionStage<Long> count = session.rowOperation(sql) |
|
56797 | 386 |
* .set("param", value, AdbaType.VARCHAR) |
387 |
* .foo() |
|
388 |
* .submit() |
|
389 |
* .getCompletionStage(); |
|
390 |
* } |
|
391 |
* </pre> |
|
392 |
* |
|
393 |
* <p> |
|
394 |
* Notice that there are no casts, yet both standard methods an the vendor extension |
|
395 |
* method foo can be referenced. This is possible only if the implementation exposes |
|
396 |
* all the necessary types and provides covariant overrides for every method that |
|
397 |
* returns one of those types. Implementations are expected (required?) to do this. |
|
398 |
* </p> |
|
399 |
* |
|
400 |
* <p> |
|
401 |
* If an implementation does not expose any implementation specific methods or |
|
402 |
* types, that implementation is not required to provide covariant overrides that |
|
403 |
* return implementation specific types.</p> |
|
404 |
* |
|
405 |
* |
|
56380 | 406 |
*/ |
56475 | 407 |
package jdk.incubator.sql2; |
56479 | 408 |