GSSCredential
Mark Rotteveel
mark at lawinegevaar.nl
Tue Jun 11 14:54:48 UTC 2019
On 2019-06-10 17:06, Douglas Surber wrote:
>> Given using proxies and reflection is very common in JDBC drivers
>> and related tools and libraries (especially with `DataSource`
>> related things), declaring as `requires static` is not an acceptable
>> solution. Declaring with `requires` will be the minimum necessary to
>> ensure proper functionality and the least amount of surprise.
>> Probably `requires transitive` is better as JDBC drivers will need
>> to actually implement this method as well. Otherwise, the driver
>> will need to use `requires static`, `requires` or `requires
>> transitive` themselves; although I have actually not seen
>> modularized JDBC drivers yet so maybe that is of lesser importance.
>
> As a driver implementer I have no problem with the driver
> module-info.java including 'requires static java.security.jgss'. The
> driver would use 'requires static' so that driver users would not have
> to include java.security.jgss unless they actually used it.
My point was more that the java.sql module at minimum will need to
declare `requires java.security.jgss` to avoid nasty surprises with
proxies and reflection. The `requires` dependency isn't inherited, but
it will at least prevent NoClassDefFoundErrors at runtime as the module
will be loaded and present.
> Proxying requiring java.security.jgss is a bigger concern. As you say,
> proxying a very common in stacks that use JDBC. I doubt any of our
> customers would care. I have no idea if there are any JDBC users that
> require an absolutely minimal module set and that also use proxying.
I doubt users of JDBC will look to minimize dependencies, but that it is
all too easy to use that as an excuse not to consider the impact of
these types of changes.
> Sure this can be just a proprietary extension; there no real necessity
> that it be part of the standard. But from that perspective there isn't
> much need for a JDBC standard at all.In spite of all the
> standardization around SQL, the various databases are all quite
> different. It is hard to write a vendor independent JDBC app of much
> sophistication.
I'd beg to differ, there are a lot of tools that build on the
foundations of JDBC, and those tools only exists because JDBC offers a
common API. And JDBC - with all its problems - is one of the better
database APIs compared with other languages.
> But since we have a JDBC standard. since GSS is itself
> a standard, and since using GSS to authenticate to a database is
> common enough, it seemed reasonable to add GSS support to JDBC. Oracle
> is not the only vendor to want to support GSS. I know SqlServer does
> also. I can't say about other vendors.
I accept that, but then, shouldn't we go all out and also add it to
DriverManager (DriverManager.getConnection(String url, GSSCredential
credential)) and to CommonDataSource
(CommonDataSource.setGSSCredential(GSSCredential) or DataSource
(DataSource.getConnection(GSSCredential))? Why only to
ConnectionBuilder? Would repeatedly using it in a data source even work
(or would that require a different approach)?
If there is such a need, wouldn't ConnectionBuilder be the least
relevant API to add it?
> Mostly I am disappointed that Jigsaw has such a profound effect on API
> design. Without Jigsaw this question would never have arisen.
Yes, I agree. But I'm also surprised there isn't anything in the
java.security package (part of java.base) that could serve as a
parent-interface for GSSCredential or as an alternative way to get
credentials.
In any case, I don't mind adding this to JDBC, but we will need to
carefully consider if the module dependency should be `requires` or
`requires transitive`. I don't think using only `requires static` is a
good idea.
If we do want to minimize the module dependency to only when it is
really necessary, then we'll need to look for a more convoluted
solutions.
Example of such a convoluted approach:
public interface WithGSSCredential {
void setGSSCredential(GSSCredential gssCredential);
}
Then if implementations want to use it, they would need to implement it
as an extra interface, and users would need to explicitly unwrap to that
interface to set it. As implementations that make this explicit choice
will depend on the module anyway, the reflection or proxy headache will
go away. Although workable, it wouldn't win a beauty contest.
Or maybe
public interface CredentialSource<T> {
T getCredential();
}
and in ConnectionBuilder:
ConnectionBuilder setCredentialSource(CredentialSource<?>
credentialSource)
and maybe add a simple wrapper around GSSCredential in JDBC, eg
public GSSCredentialSource implements CredentialSource<GSSCredential> {
private final GSSCredential credential;
public GSSCredentialSource(GSSCredential credential) {
this.credential = credential;
}
public GSSCredential getCredential() {
return credential;
}
}
Alternatively, in ConnectionBuilder, just use
<T> ConnectionBuilder setCredential(T credential);
This would allow more flexibility (other credential types could be
used), but these last two solutions lead to an unclear API (or at least:
unclear expectations).
There are probably better solutions though, but right now, none come to
mind.
It all comes down to the question: do we care about extending the module
dependencies of JDBC or not?
Mark
More information about the jdbc-spec-discuss
mailing list