[JAVA-213] Make the Mongo class proxy safe Created: 08/Nov/10 Updated: 05/Dec/17 Resolved: 28/Apr/12 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | API, Codecs |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Major - P3 |
| Reporter: | ZedroS | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 2 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
Currently, when calling new Mongo() the following happen:
When using reflection tools like cglib to build a proxy around a class, a common behaviour is to call the default constructor to wrap around it (through a subclass). This doesn't work with the Mongo class (or could in a misleading way if there's a local mongo server listening on the defaults port, which could change, esp in production). IMHO, the best approach here would be to have an explicit call to mongo to open the connection. However, at "worst", a way to setup the default settings could be enough, esp. if these settings can be done through java. One could also consider not providing a default constructor (since the current one isn't clean), but it would mean more work when proxying around. thanks in advance |
| Comments |
| Comment by Jeffrey Yemin [ 28/Apr/12 ] | |||||
|
Since zero-arg Mongo constructor no longer tries to connect to a local instance, closing this. Please comment if you disagree. | |||||
| Comment by Jeffrey Yemin [ 02/Feb/12 ] | |||||
|
@Kevin, the current version of the driver behaves as you indicate. Without mongod running, this code:
doesn't throw any exception until the call to drop(). Can this be closed, or is there more to it? | |||||
| Comment by Kevin Thomas [ 23/Mar/11 ] | |||||
|
I agree that it should be possible to construct a Mongo object without establishing a connection to the database. In its current form, the Mongo object causes application initialisation to fail in Spring applications that inject Mongo objects into other objects. This makes it very difficult to make Spring applications resistant to Mongo failures, and forces such applications to be started AFTER the Mongo database, thus reducing operational flexibility. | |||||
| Comment by Remon van Vliet [ 27/Jan/11 ] | |||||
|
The issue is related to the Proxy design pattern I think, not http ones. Am I misunderstanding your comment? | |||||
| Comment by Kornelis Sietsma [ 27/Jan/11 ] | |||||
|
Note that this causes an extremely painful problem on Ubuntu systems (at least) - if you have "useSystemProxies" set in /usr/sun-java-6/net.properties, it sets Java to use the system-wide proxy properties by default. However, it doesn't seem to set "nonProxyHosts" properly! | |||||
| Comment by Remon van Vliet [ 21/Dec/10 ] | |||||
|
I agree that a DB connection should be established when an operation is performed that requires one. For us having the Mongo(..) constructors throwing exceptions means our dependency injection framework (Google Guice) in our case fails to inject Mongo or related classes but cannot (or will not) display the actual cause of the failed injection. This complicates resolving configuration or code issues quite a bit. | |||||
| Comment by ZedroS [ 21/Dec/10 ] | |||||
|
I can't do ProxiedMongo(){ For the lazy proxy matter, it simply breaks its intend: the db connection would happen on each lazy proxy creation, not when actually used. On the bigger picture it would mean also I have to inject this ProxiedMongo everywhere, considering that:
| |||||
| Comment by Eliot Horowitz (Inactive) [ 09/Nov/10 ] | |||||
|
Why can't you do ProxiedMongo(){ | |||||
| Comment by ZedroS [ 09/Nov/10 ] | |||||
|
hi Eliot Thanks for your answer The issue is linked with proxying, in my case in the context of Wicket but it could happen to anyone using proxy. To create a proxy, the approach is usually to extend the proxied class through a subclass. Then a new instance of the subclass will be created, allowing to intercept each call made to the proxied class (and then do whatever needed). In the case of the mongo class, having such subclass doesn't work. Indeed, the subclass must call the parent constructor, and goes at the parameter less constructor. For example like this: ProxiedMongo(){ calling super here trigger this default settings connection mechanism, which fails when there's no locally available mongodb instance (in reality, tools like CGLib are used for this subclass creation, which is then done automatically). What's done next after the proxying is deeply use case specific. In my own use case, it does lazy proxing on injected field: first only an "empty" proxy is done. If and when it's first called, then the real instance of the mongo class will be fetched and used. Used in a web framework, this helps avoiding page getting too big (full of injected members of which most aren't used on every request). | |||||
| Comment by Eliot Horowitz (Inactive) [ 09/Nov/10 ] | |||||
|
I don't think a config option for overriding localhost makes sense. Why can't you just put the mongo uri string in a config file and instantiate with that? | |||||
| Comment by ZedroS [ 09/Nov/10 ] | |||||
|
what would be your preferred option ? For example, if I was to provide a patch providing a config file for the default settings, would it be ok for you ? thanks again | |||||
| Comment by Eliot Horowitz (Inactive) [ 08/Nov/10 ] | |||||
|
Overall this is the API most people seem most comfortable with. |