Re: SQLJSON - Mailing list pgsql-jdbc

From Álvaro Hernández Tortosa
Subject Re: SQLJSON
Date
Msg-id 5590E08E.1050806@8Kdata.com
Whole thread Raw
In response to Re: SQLJSON  (Christopher BROWN <brown@reflexe.fr>)
List pgsql-jdbc

On 28/06/15 23:11, Christopher BROWN wrote:
As we've seen from a recent discussion on this list, there's apparently a lot of users still downloading old versions of the driver.  If you embed a version of the API, then (unless a user derives their own version of the driver), you prevent the user from independently changing the JSONP version.  The RI is even more subject to this, as it may require updates to fix bugs.

Anyone compiling client code requiring use of the JSONP API will need to have that API in their compiler classpath.  Many of the "make it just work" users are likely to compile their JDBC code against the JDBC classes and interfaces in the JDK classpath without requiring to add the PostgreSQL JDBC driver to the compiler classpath.  They may or may not already have a version of the JSONP API in their classpath (probably will if compiling for a Java EE application server, not so likely otherwise).  They will of course need the PostgreSQL JDBC driver in their classpath for compiling if they use any PGxxx classes.

The general classloading strategy mandated is that parent classloaders should be used to load classes before child classloaders.  Many application servers however will lookup classes from embedded libraries (WEB-INF/lib) first, but this varies from one server to another, and often based on configuration options.  OSGi (and possibly Java9 modules) allow classloading from classloader graphs.  In any case, suppose that your application container defines a more recent version of the API than the driver: you'll need to hack the driver to be able to use the newer APIs.  Suppose that the driver embeds a more recent version of the API: you'll get classloading errors because you refer to methods or fields that don't exist in the application server's version.  And of course, if some other helpful library also embeds the JSONP API (or you have an alternative to the RI in your classpath, expecting a different version of the API), say a web services library or a persistence in WEB-INF/lib, you'll have other types of errors.

One of my colleagues is already using JSONB with PostgreSQL, by reading and writing stringified JSON using Jackson.  I don't know how a meaningful (accurate) study could be conducted for more insight into what prospective users would select, especially as that would in turn depend upon what is decided here.  Self-fulfilling prophecies, etc.

It would make sense to make few assumptions about what getObject() should return, because in some cases you'd want an Object Model view, and in other cases access to a parser or generator (because of improved performance).  It would make sense for me to be able to cast to a PGxxx object, in turn providing access to either a fully-constructed JSON object tree, or as a push/pull parser.  In any case, the PostgreSQL JSONB support isn't SQL-neutral, as it defines custom operators and lots of specific stuff anyway (the PGxxx object via getObject() to make it accessible via JDBC pools that wrap statements and resultsets).  You currently can't write database-neutral JSON/SQL, so until JSON is standardised at SQL level, and at JDBC level, I can't see anything wrong with a specific driver dependency.

Performance is better through streaming APIs because you create less objects, using less memory, with less GC pressure.  You can also skip through lots of data thereby avoiding lots of heap allocations.

The solution that would make most sense, would be to provide a version that embeds the API + RI, and a version that doesn't (the latter version would be compiled in the same way, it would just require that the API be made available by the host application).

    Hi Christopher.

    I don't have any objection to building two different packages or driver versions, if that makes sense.

    However, I don't see the point you make about the API. Although correct, it's only so from a theoretical perspective. The API is meant to be stable, and it will surely be for quite some years. And if it changes, it will be a substantial change that would require linking with the correct library and surely a code change. A bigger problem than dealing with classloaders. But until then (if that ever happens), the API will not change, and thus including it in the JDBC driver will never conflict with that being included in any transitive dependency, as it would be the same version (and if it changes, a new driver version would be required anyway).

    The RI admittedly is more subject to change (bug fixes, performance improvements), but being a RI:

- It's not expected to change frequently
- Few would be using it anyway

    So I don't expect those collisions to be frequent either.

    All in all, while theoretically true, we need to think practically: what is the likelihood of this happening with the API? I'd say zero. With the RI? Low enough. Thus I'd follow the idea of two separate packages, but one with the API the other with API+RI, having the latter become the default version of the driver and calling the former something like the "non-json-parser" version.

     Regarding compile-time dependencies, having the API on the driver, also non-JavaEE7 users would be happy just by including the driver as a compile-time dependency. Not a huge deal. And JavaEE7 users would be serviced without this need.

    Regards,

    Álvaro


-- 
Álvaro Hernández Tortosa


-----------
8Kdata




--
Christopher


On 28 June 2015 at 22:40, Álvaro Hernández Tortosa <aht@8kdata.com> wrote:

On 28/06/15 22:32, Christopher BROWN wrote:

Embedding the API will cause classloader conflicts for those who already have the API in their classpath.  Same goes for embedding the reference implementation.


    Hi Christopher. May you elaborate on which conflicts may it create? The API is quite stable, so I don't see a chance for conflicts. The RI may be a more likely source of conflicts, yet I see them quite unlikely. And if so, if it would be so important to avoid them, different packages may be provided.

The service loader API can be problematic for OSGi users, as it isn't very helpful for hot reloading of classes.  The PostgreSQL JDBC driver currently works well in such environments, it would be unfortunate to lose that advantage through an attempt to help out another category of users.

    I'm no OSGI expert, so I may fail to understand this properly, but how problematic this is? Is hot reloading the JDBC driver a big issue?

This shouldn't be the only way of selecting an implementation, and bundling a given version of the API + RI shouldn't be the only build option. I'm certainly not against making this Just Work, but here there's a possibility that all this extra stuff could actually cause things to break .

    So if there are problems even bundling the API, what solution do you suggest to provide end users with a facility to read their new, fancy and much hyped jsonb columns?

    If there is none, I'd definitely study what the percentage of people would have problems with the proposed approach (API + RI?).


    Regards,

    Álvaro
-- 
Álvaro Hernández Tortosa


-----------
8Kdata



Le 28 juin 2015 22:11, "Álvaro Hernández Tortosa" <aht@8kdata.com> a écrit :

On 28/06/15 15:56, Dave Cramer wrote:
So I think we should support JSR 353 at the very least Whether we extend the result set or not we can at a minimum return a JsonValue  from getObject

I agree with Alvaro, 99% of the users would just like a JsonValue returned. It would be nice if we could design this so more advanced users could plug in their parser of choice.

    Yes, at least to have a JsonValue would be a really nice addition.

    To plug your parser, JSR 353 follows Java's standard SPI and is as simple as write the fqcn of the driver implementation to META-INF/services/javax.json.spi.JsonProvider. So rather than asking everybody to do that, it would be even nicer to embed the JSR353 Reference Implementation (a mere 64Kb) and let advanced users override the parser by writing the services file. I know that adding external dependencies is not everybody's favorite idea here, but I really believe it definitely help (most) users and would allow us to ship a driver that would work out-of-the-box with JSON.

    Regards,

    Álvaro


-- 
Álvaro Hernández Tortosa


-----------
8Kdata



Dave Cramer

dave.cramer(at)credativ(dot)ca
http://www.credativ.ca

On 28 June 2015 at 06:00, Álvaro Hernández Tortosa <aht@8kdata.com> wrote:

On 28/06/15 11:51, Markus KARG wrote:
It is not *us* who let the JSON users down, it is the PostgreSQL protocol
guys who did not add any useful support for JSON. A driver is not a
compensation for missing product features, it is just a thin wrapper around
the base product's features.
    To have proper JSON support at the protocol level (something which I'd love to have) only translates to more performance, no more functionality. So is a nice-to-have, not a must-to-have (as is supporting PostgreSQL's json data types).

I mean, what happens if the application shall work with a different product?
If you rely on non-JDBC-features, you're screwed. So a profession
application using JSON should ALWAYS come with JSR 253 anyways.
    We have had to extend JDBC in several ways in the past. We should do it again, now, in the best possible manner (getObject, PGResultSet, whatever). And then, if JDBC adds support in the future, retrofit into it. But not wait until then, because we don't even know if that would even happen.

    Cheers,


    Álvaro


--
Álvaro Hernández Tortosa


-----------
8Kdata




-----Original Message-----
From: pgsql-jdbc-owner@postgresql.org
[mailto:pgsql-jdbc-owner@postgresql.org] On Behalf Of Álvaro Hernández
Tortosa
Sent: Sonntag, 28. Juni 2015 11:44
To: pgsql-jdbc@postgresql.org
Subject: Re: [JDBC] SQLJSON


On 28/06/15 11:17, Markus KARG wrote:
I do not see the benefit of that effort, as getting JSON as a LONG VARCHAR
and then parsing it on behalf of the application is pretty simple and
straightforward. My vote would be to not do anything until JDBC 4.3 of
JDBC
5.0 provides a standard API for dealing with JSON inside of the driver or
at
least PostgreSQL 9.5 or PostgreSQL 10 provides a streaming protocol for
JSON
and / or XML.
      Don't do anything?

      And let Java PostgreSQL users down, without a (driver, supported)
means of getting JSON out of their database? So we make the "marketing"
that 9.4 is all about jsonb and the NoSQL replacement yet you cannot do
JSON with Java?

      Really?

      User's don't care about extreme performance. Users care about easy
of use and decent set of features. Adding JSON support, even thought
it's not the most performant one is something we should be doing as
quickly as possible.

      Regards,

      Álvaro





--
Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-jdbc





pgsql-jdbc by date:

Previous
From: Christopher BROWN
Date:
Subject: Re: SQLJSON
Next
From: Álvaro Hernández Tortosa
Date:
Subject: Re: SQLJSON