Thread: 8.0 drivers released.
With the 8.0 server release coming later this week, I've put up a new set of JDBC drivers. I haven't had time to write up a full set of release notes, so this email will have to suffice for now... Naturally there are a huge number of minor improvements and fixes, but these are the big things in 8.0: - True V3 protocol support. - Savepoints. - No more "idle in transaction" problems. - Binary data doesn't use fifty times the necessary memory. - SSL connection customization - driver configuration via properties file - 5.0 JDK compiles Major compatibility issues that come to mind immediately. The driver now always uses some form of server prepared statement. This means that all data is now strongly typed instead of mashed together into a query string for the server to figure out. If you have an application that uses setString(x, myString) for every type, you are not going to be happy. The driver needs to know what the real column type is in the database and it infers this from the setXXX call you make. This presents some tricky problems when dealing with postgresql datatypes that do not match up exactly with Java datatypes that are only solved by using a custom PGobject subclass to pass both the data and the correct type to the driver. This also extends to null values, no longer is setObject(x, null) valid because it does not contain type information for the driver to use. Previously Statement.executeQuery("INSERT ... ; SELECT currval('myseq')"); would return a ResultSet. This is no longer true and I don't believe it was ever strictly legal. This should be correctly written in separate queries or: Statement.execute("INSERT ...; SELECT currval('myseq')"); Statement.getMoreResults(); ResultSet rs = Statement.getResultSet(); Calling PreparedStatement.setBinaryStream now requires a correct length argument. Previously Integer.MAX_VALUE or similar could be used and it would read the stream to completion, but with the ability to stream data directly to the server and not use up outrageous amounts of memory means that we need to know the correct length from the outset. Kris Jurka
On Monday 17 January 2005 13:48, Kris Jurka wrote: > With the 8.0 server release coming later this week, I've put up a new set > of JDBC drivers. I haven't had time to write up a full set of release > notes, so this email will have to suffice for now... > > Naturally there are a huge number of minor improvements and fixes, > but these are the big things in 8.0: > > - True V3 protocol support. > - Savepoints. > - No more "idle in transaction" problems. > - Binary data doesn't use fifty times the necessary memory. > - SSL connection customization > - driver configuration via properties file > - 5.0 JDK compiles > > Major compatibility issues that come to mind immediately. > > The driver now always uses some form of server prepared statement. This > means that all data is now strongly typed instead of mashed together into > a query string for the server to figure out. If you have an application > that uses setString(x, myString) for every type, you are not going to be > happy. The driver needs to know what the real column type is in the > database and it infers this from the setXXX call you make. This presents > some tricky problems when dealing with postgresql datatypes that do not > match up exactly with Java datatypes that are only solved by using a > custom PGobject subclass to pass both the data and the correct type to the > driver. This also extends to null values, no longer is setObject(x, null) > valid because it does not contain type information for the driver to use. > > Previously Statement.executeQuery("INSERT ... ; SELECT currval('myseq')"); > would return a ResultSet. This is no longer true and I don't believe it > was ever strictly legal. This should be correctly written in separate > queries or: > > Statement.execute("INSERT ...; SELECT currval('myseq')"); > Statement.getMoreResults(); > ResultSet rs = Statement.getResultSet(); > > Calling PreparedStatement.setBinaryStream now requires a correct length > argument. Previously Integer.MAX_VALUE or similar could be used and it > would read the stream to completion, but with the ability to stream data > directly to the server and not use up outrageous amounts of memory means > that we need to know the correct length from the outset. > > Kris Jurka Hi! I tried using postgresql-8.0.309.jdbc2.jar (and jdbc3) and got the following NullPointerException: Caused by: java.lang.NullPointerException at org.postgresql.Driver.getDefaultProperties(Driver.java:84) at org.postgresql.Driver.connect(Driver.java:167) at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:599) Any explaination? -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager gpg public_key: http://dev.officenet.no/~andreak/public_key.asc ------------------------+---------------------------------------------+ OfficeNet AS | Can i wash my clothes with my dvd drive? | Hoffsveien 17 | Or do i need to replace it with a washing | PO. Box 425 Skøyen | machine?? | 0213 Oslo | | NORWAY | | Phone : +47 22 13 01 00 | | Direct: +47 22 13 10 03 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+
Attachment
Andreas Joseph Krogh wrote: > NullPointerException: > Caused by: java.lang.NullPointerException > at org.postgresql.Driver.getDefaultProperties(Driver.java:84) > at org.postgresql.Driver.connect(Driver.java:167) > at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:599) Driver.java:84 is: Enumeration urlEnum = getClass().getClassLoader().getResources("org/postgresql/driverconfig.properties"); I guess that org.postgresql.Driver is being loaded by the bootstrap classloader (getClassLoader() returns null). How exactly are you getting the driver jar into the classpath? -O
On Tuesday 18 January 2005 12:58, you wrote: > Andreas Joseph Krogh wrote: > > NullPointerException: > > Caused by: java.lang.NullPointerException > > at org.postgresql.Driver.getDefaultProperties(Driver.java:84) > > at org.postgresql.Driver.connect(Driver.java:167) > > at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:599) > > Driver.java:84 is: > > Enumeration urlEnum = > getClass().getClassLoader().getResources("org/postgresql/driverconfig.prope >rties"); > > I guess that org.postgresql.Driver is being loaded by the bootstrap > classloader (getClassLoader() returns null). How exactly are you getting > the driver jar into the classpath? I saw that line too, but would never have guessed that getClassLoader() returnes null(don't know much about classloaders). I'm trying to load a ConnectionPool in Tomcat-5.0.28 and had my pg.jar in $TOMCAT_HOME/common/endorsed/, when I moved it to $TOMCAT_HOME/common/lib/ it works ok. It used to work in common/endorsed with previous releases(including 8.0.beta4 which is the last one I tried before 8.0 final). Anyway, the problem is now gone, thanks! -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager gpg public_key: http://dev.officenet.no/~andreak/public_key.asc ------------------------+---------------------------------------------+ OfficeNet AS | Can i wash my clothes with my dvd drive? | Hoffsveien 17 | Or do i need to replace it with a washing | PO. Box 425 Skøyen | machine?? | 0213 Oslo | | NORWAY | | Phone : +47 22 13 01 00 | | Direct: +47 22 13 10 03 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+
Attachment
Am Montag, 17. Januar 2005 13:48 schrieb Kris Jurka: > With the 8.0 server release coming later this week, I've put up a new set > of JDBC drivers. I haven't had time to write up a full set of release > notes, so this email will have to suffice for now... Could you please not name the tarballs "postgresql-8.0.309.src.tar.gz" etc. I think there is a chance that this will be confused with postgresql proper. Maybe "postgresql-jdbc" is a better stem. -- Peter Eisentraut http://developer.postgresql.org/~petere/
Oliver Jowett wrote: > Andreas Joseph Krogh wrote: > >> NullPointerException: >> Caused by: java.lang.NullPointerException >> at org.postgresql.Driver.getDefaultProperties(Driver.java:84) >> at org.postgresql.Driver.connect(Driver.java:167) >> at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:599) > > Driver.java:84 is: > > Enumeration urlEnum = > getClass().getClassLoader().getResources("org/postgresql/driverconfig.properties"); > > I guess that org.postgresql.Driver is being loaded by the bootstrap > classloader (getClassLoader() returns null). How exactly are you getting > the driver jar into the classpath? I can reproduce the exception by running test code when the driver is loaded from the bootstrap classpath ('-Xbootclasspath/a:jars/postgresql.jar') It seems reasonable to fall back to the system classloader if the driver was loaded from the bootstrap classloader. I will commit a change to do this shortly. -O
On Tuesday 18 January 2005 17:17, Oliver Jowett wrote: > I can reproduce the exception by running test code when the driver > is loaded from the bootstrap classpath > ('-Xbootclasspath/a:jars/postgresql.jar') > > It seems reasonable to fall back to the system classloader if the > driver was loaded from the bootstrap classloader. I will commit a > change to do this shortly. Another reasonable course of action might be to try the context classloader: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html#getContextClassLoader%28%29 This would typically have the system classloader in its parent hierarchy, but it may also give you access to locations that the system classloader cannot see.
Vadim Nasardinov wrote: > Another reasonable course of action might be to try the context classloader: > http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html#getContextClassLoader%28%29 > > This would typically have the system classloader in its parent hierarchy, > but it may also give you access to locations that the system classloader > cannot see. I am of the opinion that thread context classloaders are evil and should be avoided if at all possible -- they make code fragile and sensitive to caller context (almost by definition!) Also it'd mean that we would have to load the defaults on every call to getConnection(), rather than once per Driver instance (i.e. most probably exactly once). Does it make sense to have the driver defaults change depending on who is obtaining the connection? -O
On Tuesday 18 January 2005 18:07, Oliver Jowett wrote: > I am of the opinion that thread context classloaders are evil If that's a moral judgment, I have no comment. If a technical one -- where's the evidence? (My ignorance prevents me from taking sides in this argument. I'm just curious.) > and should be avoided if at all possible -- they make code fragile > and sensitive to caller context (almost by definition!) It doesn't have to be any more sensitive than the current situation. Current code is also sensitive to caller context. The Driver.class's classloader depends on the caller. The thrust of your argument seems to be that this is a one-time dependency. Once established, it doesn't changed for the remainder of the class's lifecycle. Well, the same could be true of a context-classloader-based implementation. When you register the Driver instance with the DriverManager in the static initializer, a (weak) reference to the current context classloader may be saved in a static field. The field can be used later on in the getDefaultProperties() method, if getClass().getClassLoader() turns out to be null. (BTW, couldn't this be Driver.class.getClassLoader() instead?) > Does it make sense to have the driver defaults change depending on > who is obtaining the connection? The fact that this is nonsensical is irrelevant. Changing defaults on a per connection basis has never been proposed. More to the point, can someone explain what /org/postgresql/driverconfig.properties files are actually used for? Google doesn't seem to know: http://www.google.com/search?q=%22driverconfig.properties%22 Without knowing what this feature is actually used for, I'd speculate groundlessly that the context-classloader-based implementation is more likely to work in the application server scenario. Within the same app server instance, multiple *.properties files are likely to exist for use by different apps. These files aren't likely to be on the CLASSPATH. Rather, they're likely to be in a per-application config directory that the system classloader can't see.
Vadim Nasardinov wrote: > On Tuesday 18 January 2005 18:07, Oliver Jowett wrote: > >>I am of the opinion that thread context classloaders are evil > > > If that's a moral judgment, I have no comment. If a technical one -- > where's the evidence? (My ignorance prevents me from taking sides in > this argument. I'm just curious.) It's just an opinion. I have been bitten by context classloader weirdness often enough that I try to avoid it whenever I can. If you use the CCL, you have added hidden coupling between whoever sets the CCL and the use of the CCL. Hidden coupling is usually bad -- it makes the code less obvious and more prone to context-sensitive breakage. Many libraries depend on particular CCL settings *and do not document this anywhere*. Really hidden coupling! It gets worse if you are in a managed environment -- the environment may be using the CCL for its own purposes, and your code may not even have permission (security policy) to change the CCL. To use a CCL-using library reliably in that sort of environment, you end up setting and resetting the CCL on every call to the library (might involve writing a privileged wrapper -- ugh!). This defeats the purpose of having a CCL in the first place. Why not just configure the library with the right ClassLoader via another mechanism, or explicitly pass a ClassLoader to those methods that need to do class/resource loading? Sorry .. it's a pet peeve of mine :) Given that there is a non-ClassLoader-aware layer (DriverManager) between the JDBC client and JDBC driver that we cannot change, if we needed to pass a ClassLoader then using the CCL is probably the best way. But I don't see that we *need* to pass a ClassLoader at all; see below. > When you register the Driver instance with the DriverManager in the > static initializer, a (weak) reference to the current context > classloader may be saved in a static field. The field can be used > later on in the getDefaultProperties() method, if > getClass().getClassLoader() turns out to be null. Ok, but I don't understand why you'd want to jump through all these hoops in the first place. It is even less predictable when the static initializer will be run (and therefore what the CCL will be set to at that point). What's the point? > (BTW, couldn't this > be Driver.class.getClassLoader() instead?) Yes. getClass() tends to be a bit friendlier to anything that tweaks the bytecode, though, since a .class reference compiles down to a call to Class.forName() which breaks if the class is renamed, etc. >>Does it make sense to have the driver defaults change depending on >>who is obtaining the connection? > > The fact that this is nonsensical is irrelevant. Changing defaults on > a per connection basis has never been proposed. *shrug* It's the logical conclusion of using the CCL to find the defaults. The context can change -- why do the defaults *not* change if you change the context? What is special about the context of the first call to getConnection(), or the first action that happens to cause class initialization (if you go with magic in the static initializer)? > More to the point, can someone explain what > /org/postgresql/driverconfig.properties files are actually used for? Briefly, configuring driver defaults globally without having to mess around with every application URL. See http://archives.postgresql.org/pgsql-jdbc/2004-10/msg00023.php for the thread that spawned it. > Without knowing what this feature is actually used for, I'd speculate > groundlessly that the context-classloader-based implementation is more > likely to work in the application server scenario. Within the same > app server instance, multiple *.properties files are likely to exist > for use by different apps. These files aren't likely to be on the > CLASSPATH. I don't think it makes sense to allow a particular application to override a bit of "global" data for the driver that is shared between multiple applications. App servers can reconfigure the driver either globally or on a per-application basis easily enough anyway. > Rather, they're likely to be in a per-application config directory that the system classloader can't see. The system classloader only gets involved when the driver has been loaded in the *bootstrap* classpath. In all other cases, we use the classloader that loaded the driver to load the defaults. Still, this will usually be a classloader that cannot see the per-application resources. If an application wants a customized set of defaults, it can arrange for a separate instance of the driver packaged with the appropriate defaults to be loaded with the application; in that case, there's no problem with finding the right classloader. -O
On Tuesday 18 January 2005 23:12, Oliver Jowett wrote: > Ok, but I don't understand why you'd want to jump through all these > hoops in the first place. Because you may want to be a good citizen in the app server world, where defaulting to the system classloader still seems suboptimal to me. This use case has been adequately addressed in your reply though. I don't want to press this line of reasoning any further. > It is even less predictable when the static initializer will be run > (and therefore what the CCL will be set to at that point). What's > the point? The same goes for getClass().getClassLoader(). It's not predictable what this returns. > It's the logical conclusion of using the CCL to find the defaults. I don't see how that follows. > What is special about [...] the first action that happens to cause > class initialization (if you go with magic in the static > initializer)? It's special because it determines the result of getClass().getClassLoader(). In other words, it's special because current code treats as such: Enumeration urls = getClass().getClassLoader(). getResources("/org/postgresql/driverconfig.properties"); For the sake of completeness, what do you think of doing nothing in the case when the driver is loaded by the bootstrap classloader? In other words, wrap the affected chunk of code in the following conditional: if (getClass().getClassLoader() != null) { // load the /org/postgresql/driverconfig.properties files } Thanks, Vadim P.S. > > (BTW, couldn't this be Driver.class.getClassLoader() instead?) > > Yes. getClass() tends to be a bit friendlier to anything that tweaks > the bytecode, though, since a .class reference compiles down to a > call to Class.forName() which breaks if the class is renamed, etc. Out of curiosity, is it a formal policy of the pgsql-jdbc project to be friendly to bytecode mungers? What other guidelines does one need to be mindful of?
Vadim Nasardinov wrote: > On Tuesday 18 January 2005 23:12, Oliver Jowett wrote: >>It is even less predictable when the static initializer will be run >>(and therefore what the CCL will be set to at that point). What's >>the point? > > The same goes for getClass().getClassLoader(). It's not predictable > what this returns. Two comments: Firstly, your statement is not true. getClass().getClassLoader() will always return the classloader that was used to load the driver class, which *is* predictable. You can always, for example, put driverconfig.properties in the path of the same classloader that loads the driver (at worst, by packaging it directly in the driver jar) and the driver will find it. In contrast, if you're relying on the CCL, you have essentially no guarantees about where it will search. It could be a completely unrelated CL that can't even see the driver jar! Secondly, I think you missed my point. It is the *timing* of initialization that I am concerned about. Timing of class initialization is hard to predict; how do you make sure that the CCL is correctly set when this happens? How do you document this so that users don't get confused? It seems unreasonable to require someone who just wants to use the JDBC driver to have to understand the mechanics of class initialization and guard against accidentally causing initialization before they're ready! >>What is special about [...] the first action that happens to cause >>class initialization (if you go with magic in the static >>initializer)? > > It's special because it determines the result of > getClass().getClassLoader(). It does not. getClass().getClassLoader() always returns the classloader that loaded org.postgresql.Driver, regardless of the environment when class initialization is triggered. The returned classloader will not change during the lifetime of a particular copy of the Driver class. If you are using the CCL to locate the defaults, then either the context set during initialization is somehow special (if you only load the defaults once) or you must load the defaults on every getConnection() and they can change depending on the caller's context. I don't like either behaviour. > For the sake of completeness, what do you think of doing nothing in > the case when the driver is loaded by the bootstrap classloader? In > other words, wrap the affected chunk of code in the following > conditional: > > if (getClass().getClassLoader() != null) { > // load the /org/postgresql/driverconfig.properties files > } It could do that (it does that if the system classloader is null) but it seems less useful -- why can the driver suddenly no longer load defaults if it ends up in the bootstrap classpath? Ideally we need some way to get resources directly from the bootstrap classloader, but ClassLoader does not give us a way to do that. Using the system classloader seems like the best approximation. >>Yes. getClass() tends to be a bit friendlier to anything that tweaks >>the bytecode, though, since a .class reference compiles down to a >>call to Class.forName() which breaks if the class is renamed, etc. > > Out of curiosity, is it a formal policy of the pgsql-jdbc project to > be friendly to bytecode mungers? What other guidelines does one need > to be mindful of? Personally I write lots of other code that has to be friendly to bytecode mungers, so it becomes force of habit. It's not a formal policy, just one of my own code hygiene rules. -O
On Wednesday 19 January 2005 15:53, Oliver Jowett wrote: > Firstly, your statement is not true. getClass().getClassLoader() > will always return the classloader that was used to load the driver > class, which *is* predictable. That part is predictable, yes. What's not predictable is which *particular* classloader this will be. > You can always, for example, put driverconfig.properties in the path > of the same classloader that loads the driver Not always, you can't. > In contrast, if you're relying on the CCL, you have essentially no > guarantees about where it will search. It could be a completely > unrelated CL that can't even see the driver jar! Why is that so terrible? > Secondly, I think you missed my point. It is the *timing* of > initialization that I am concerned about. Timing of class > initialization is hard to predict; how do you make sure that the CCL > is correctly set when this happens? I think I understood your point the first time around. My counterpoint is, the current getClass().getClassLoader() approach is in a very similar boat. If one can put org/postgresql/driverconfig.properties on the same classpath as the driver, then, yes, they're all set. (Except for the bootstrap classloader case.) If they can't do that, then they're essentially in the same boat. How does one make sure that the classloader that loads org.postgresql.Driver is also the one that can find their driverconfig.properties? > How do you document this so that users don't get confused? As the first step, documenting the existence of driverconfig.properties would be nice. Other than http://archives.postgresql.org/pgsql-jdbc/2004-10/thrd2.php#00023 is it mentioned anywhere else? Does anyone actually use this? > It seems unreasonable to require someone who just wants to use the > JDBC driver to have to understand the mechanics of class > initialization and guard against accidentally causing initialization > before they're ready! It's an argument I wholeheartedly agree with. I'd just like to point out that it also applies to the current situation. > It could do that (it does that if the system classloader is null) > but it seems less useful -- why can the driver suddenly no longer > load defaults if it ends up in the bootstrap classpath? I keep forgetting to ask. How do you put the driver in the bootstrap classpath? The only way that I know of is to use one of the following flags under Sun's JRE: -Xbootclasspath -Xbootclasspath/a -Xbootclasspath/p I was under the impression that using these is very uncommon. Thanks for taking the time to answer my questions. Vadim
On Fri, 21 Jan 2005, Vadim Nasardinov wrote: > As the first step, documenting the existence of > driverconfig.properties would be nice. Other than > http://archives.postgresql.org/pgsql-jdbc/2004-10/thrd2.php#00023 > > is it mentioned anywhere else? Does anyone actually use this? > Well, it's a problem of limited resources. We've had SSL support for a year and half, but it wasn't until last week that how to set it up was documented anywhere but the mailing list. Writing documentation is neither fun nor really necessary for the developers because we already know how it works. Not ideal, but that's kind of the way it has been. As volunteer developers we're primarily users and only secondarily maintainers for other users. The need to actually use this mechanism is restricted to very specialized applications. The key addition is auto-registering custom class mappings, the additional default settings were thrown in largely because we could. Kris Jurka
Vadim Nasardinov wrote: > That part is predictable, yes. What's not predictable is which > *particular* classloader this will be. It is a different class of predictability. If you know where the driver is loaded from, you know at least one location checked by the driver's classloader -- the driver jar. You have no information about the CCL in effect at driver load time, though. >>You can always, for example, put driverconfig.properties in the path >>of the same classloader that loads the driver > > Not always, you can't. Why not? If you could put the driver jar there, why can't you also put properties there? >>In contrast, if you're relying on the CCL, you have essentially no >>guarantees about where it will search. It could be a completely >>unrelated CL that can't even see the driver jar! > > Why is that so terrible? It's much less predictable. Given information on where the driver is loaded from, you have no idea where it will load defaults from. At least with using getClass().getClassLoader(), you know at least one location (the driver jar's location), and can probably infer several more from knowledge about how you configure classpaths to load the driver from. > If one can put > org/postgresql/driverconfig.properties on the same classpath as the > driver, then, yes, they're all set. (Except for the bootstrap > classloader case.) If they can't do that, then they're essentially in > the same boat. How does one make sure that the classloader that loads > org.postgresql.Driver is also the one that can find their > driverconfig.properties? Know your environment; supply a classpath for loading the driver that includes a location that you can modify. e.g. add it to CLASSPATH, or include it in the classpath-to-load-driver-from configuration, or put it in the magic directory whose contents are included at startup, etc. > I keep forgetting to ask. How do you put the driver in the bootstrap > classpath? The only way that I know of is to use one of the following > flags under Sun's JRE: > > -Xbootclasspath > -Xbootclasspath/a > -Xbootclasspath/p > > I was under the impression that using these is very uncommon. Well, the case that triggered this thread happened by putting the driver jar in a particular directory that apparently was in the appserver's bootstrap classpath. It's not common, but I don't see why the driver should break if it happens. -O
To draw a line under this thread, here are my takeaways. The purpose of org/postgresql/driverconfig.properties is to globally configure the driver. The most consistent way to do this is to put the config file on the same path as the driver's .jar file. There are two distinct classes of users: (a) Those who have complete control over deployment of both the driver and the application that uses it. (b) Those who have limited control over their application's classpath. (For a recent example, see [1].) For Class A, the most consistent approach is to say, (a) Don't put pgsql-jdbc.jar on the boot classpath. No reason to do this. (b) If you want to configure the driver globally, put org/postgresql/driverconfig.properties in the same location as the pgsql-jdbc.jar file. For this class of users, then, the following works fine: if (getClass().getClassLoader() != null) { // load the config file } For Class B, the most consistent approach is to say, Since you don't have control over the driver's .jar file location, you're not meant to have control over its global settings. The same code works for this class of users as well. Defaulting to the system classloader strikes me as a fairly arbitrary way to avoid an NPE. I agree that using the context class loader is an equally arbitrary cop-out. On Friday 21 January 2005 15:07, Oliver Jowett wrote: > Well, the case that triggered this thread happened by putting the > driver jar in a particular directory that apparently was in the > appserver's bootstrap classpath. It's not common, but I don't see > why the driver should break if it happens. It shouldn't break. To prevent it from breaking, test the object for nullity before calling a method on it. Footnotes 1. http://archives.postgresql.org/pgsql-jdbc/2004-12/msg00212.php
Vadim Nasardinov wrote: > It shouldn't break. To prevent it from breaking, test the object for > nullity before calling a method on it. Yes, or replace the null object with something that isn't null. That's what the change I made several days does :) -O
Hi, Oliver and Vadim, Oliver Jowett schrieb: >> More to the point, can someone explain what >> /org/postgresql/driverconfig.properties files are actually used for? > > Briefly, configuring driver defaults globally without having to mess > around with every application URL. > > See http://archives.postgresql.org/pgsql-jdbc/2004-10/msg00023.php for > the thread that spawned it. One usage of it is that the new postgis.jar from PostGIS 1.0 includes such a properties file, this auto-registers the PostGIS data type extensions (PGobject subclasses) for geometry, box3d and box2d within the jdbc driver just by throwing the postgis.jar into the classpath. Note that users still can override this behaviour on a datasource or connection basis via URL and addDataType(). Markus -- markus schaber | dipl. informatiker logi-track ag | rennweg 14-16 | ch 8001 zürich phone +41-43-888 62 52 | fax +41-43-888 62 53 mailto:schabios@logi-track.com | www.logi-track.com
Attachment
Hi, Vadim, Vadim Nasardinov schrieb: >>How do you document this so that users don't get confused? > > As the first step, documenting the existence of > driverconfig.properties would be nice. Other than > http://archives.postgresql.org/pgsql-jdbc/2004-10/thrd2.php#00023 > > is it mentioned anywhere else? Does anyone actually use this? PostGIS jdbc extension uses this since Version 1.0RC2 to auto-register the PostGIS geometry types (PGobject subclasses). Markus -- markus schaber | dipl. informatiker logi-track ag | rennweg 14-16 | ch 8001 zürich phone +41-43-888 62 52 | fax +41-43-888 62 53 mailto:schabios@logi-track.com | www.logi-track.com