dev@glassfish.java.net

Re: multiple problems with empty password in creating jdbc connection pool

From: Anissa Lam <Anissa.Lam_at_Sun.COM>
Date: Tue, 08 Aug 2006 16:30:32 -0700

Muhammad Siraj Ghaffar wrote:
> Kedar Mhaswade wrote:
>
>> Hmm. It's tricky, isn't it?
>> I agree that this is rather ugly, and could be handled better.
>> You can file an RFE against configuration if the following does
>> not satisfy you.
>>
>> First problem: Connector backend (the piece of code that pings
>> the database) does not default the null value for the password
>> to mean that there is no password.
>>
>> Second problem: admin interfaces don't have any way to "explicitly"
>> remove a "property". This is especially true for admin GUI. It is
>> a rather hard problem to solve on today's admin GUI.
>> On the GUI, traditionally when a particular text field is not provided
>> (i.e. you leave it blank), it is taken to mean that that attribute
>> and/or property is removed from the configuration, if it is allowed.
>>
>> Thus, if:
>> - an attribute "a1" on an element "e1" is allowed to be empty
>> - a property "foo" anywhere in domain.xml is allowed to be empty,
>>
>> a screen with such values left bank will result in removing the
>> attribute/property on clicking "Save".
>>
>> If the value is NOT "allowed" to be empty, it is an error.
>>
>> Now, properties by design, are never allowed to have empty values.
>> Thus, an empty value for property always -> removal of the property
>> from the configuration.
>>
>> I know, this is rather bad, but the GUI unfortunately does not have
>> an explicit way to "remove" a property and distinguish it from empty
>> values.
>>
>> Should we decide to change the semantics, the GUI (several screens)
>> will need to be redesigned. (At least that's what I am told).
>
>
> I dont see the need to redesign any GUI screens to handle empty valued
> properties. Every GUI screen with additional properties has a "Delete
> Properties" button that can be used to actually remove the property.
> If the property value is empty then the user should be able to enter a
> value for the property name and leave the value empty. If this is not
> happening then that's a bug that needs to be fixed. Regardless, there
> shouldnt be any need to change the actual UI that the user sees, to
> resolve this particular case. From what I remember, this part of the
> code is reused almost everywhere, so there shouldnt be a need to make
> massive changes either. CCing gui team..
>
It is not GUI that prevents empty property value to be saved. Please
refer to
http://bt2ws.central.sun.com/CrPrint?id=6378808
Here is from the evaluation of the bug. The solution provied by the
backend is to add the 'unofficial' special string that will be
translated to "" by the backend and write out "" as property value to
domain.xml.

Evaluation

Backend treats "" empty String as removal of the property itself. This mean, unless backend changed the behaviour or have a way for setting property value to "" empty string, there is not much GUI can do.
I am transferring this bug to 'admin'. Once they design and implemented a way to set empty string value to Property, then GUI can implement that.
Here is comment from bug# 6363330

>Set empty valued property is treated by backend as request to remove property.
>This is only way to remove property from CLI, as far as it has only 'get' and 'set' command to handle dotted named attributes and properties.
>We can not re-consider this behaviour now because of backward compartibility.
>Kedar and Abhijit proposed to have the special value for property to set it to "empty" string.
>
> *** (#2 of 5): 2006-01-10 00:02:19 GMT+00:00alexandre.kravtchenko_at_sun.com

*** (#1 of 1): 2006-01-30 22:29:35 GMT+00:00 anissa.lam_at_sun.com
*** Last Edit: 2006-01-30 22:29:35 GMT+00:00 anissa.lam_at_sun.com


Anissa.

>>
>> CLI also falls short here because it treats it the same --
>> asadmin set "a.b.c.property.xyz=" will make the
>> <property name="xyx" value="anything"/> disappear from domain.xml :)
>>
>> Now comes the work around part of it. Obviously we knew this will
>> happen. So, there is a special value of a property (I wouldn't tell
>> which one -- for it is an undocumented interface) which when used
>> will do the "right" thing as you'd expect. As always, there are issues
>> with this, but I feel they are manageable.
>>
>> I'd want your RFE to actually make that "special empty value" an
>> interface.
>>
>>
>> Thanks and sorry,
>> Kedar
>>
>> Cheng Fang wrote:
>>
>>> I want to create a jdbc connection pool with a username, but empty
>>> password. In admin GUI, I filled in username field and left
>>> password field blank. I also checked (the checkbox) fields
>>> including username, password, databaseName, etc. The pool was
>>> successfully created. But in domain.xml, the <jdbc-connection-pool>
>>> element doesn't have a password property. I would expect a password
>>> property with an empty value to be added.
>>>
>>> When I ping the pool, it failed: "password credential is required."
>>> But in fact, the database doesn't need any password to connect to.
>>>
>>> After I add a empty password property to domain.xml, I was able to
>>> use the datasource.
>>>
>>> Then I decided to try 'asadmin add-resource'. I created a resource
>>> xml file (see attached) containing an empty-password property:
>>> <property name="password" value=""/>
>>>
>>> I got this error:
>>> =========================
>>> Could not add Resource Type: jdbc-connection-pool. Error Message:
>>> Operation 'setProperty' failed in 'jdbc-conn
>>> ection-pool' Config Mbean.
>>> Target exception message: Property password can not be removed.
>>> =========================
>>> Added Resource Type: jdbc-resource
>>> Command add-resources executed successfully.
>>>
>>> server.log error:
>>> [#|2006-08-08T15:11:56.480-0400|WARNING|sun-appserver-pe9.1|javax.enterprise.system.stream.err|_ThreadID=12;_ThreadName=httpWorkerThread-4848-1;_RequestID=ba754501-ec34-40e2-a7ee-35872f528a37;|
>>>
>>> javax.management.MBeanException: Operation 'setProperty' failed in
>>> 'jdbc-connection-pool' Config Mbean.
>>> Target exception message: Property password can not be removed.
>>> at
>>> com.sun.enterprise.admin.MBeanHelper.extractAndWrapTargetException(MBeanHelper.java:419)
>>>
>>> at
>>> com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:470)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.DynamicMetaDataImpl.invoke(DynamicMetaDataImpl.java:213)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.MetaDataImpl.invoke(MetaDataImpl.java:220)
>>> at
>>> com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:815)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:784)
>>> at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:77)
>>>
>>> at $Proxy1.invoke(Unknown Source)
>>> at
>>> com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:297)
>>>
>>> at
>>> com.sun.enterprise.admin.mbeans.ResourcesMBean.setProperties(ResourcesMBean.java:830)
>>>
>>> at
>>> com.sun.enterprise.admin.mbeans.ResourcesMBean.createResource(ResourcesMBean.java:653)
>>>
>>> at
>>> com.sun.enterprise.admin.mbeans.ResourcesMBean.createAResource(ResourcesMBean.java:2016)
>>>
>>> at
>>> com.sun.enterprise.admin.mbeans.ResourcesMBean.createResource(ResourcesMBean.java:1886)
>>>
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:353)
>>>
>>> at
>>> com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:336)
>>>
>>> at
>>> com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:448)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.DynamicMetaDataImpl.invoke(DynamicMetaDataImpl.java:213)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.MetaDataImpl.invoke(MetaDataImpl.java:220)
>>> at
>>> com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:815)
>>>
>>> at
>>> com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:784)
>>> at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:77)
>>>
>>> at $Proxy1.invoke(Unknown Source)
>>> at
>>> com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:297)
>>>
>>> at
>>> com.sun.enterprise.admin.jmx.remote.server.callers.InvokeCaller.call(InvokeCaller.java:56)
>>>
>>> at
>>> com.sun.enterprise.admin.jmx.remote.server.MBeanServerRequestHandler.handle(MBeanServerRequestHandler.java:142)
>>>
>>> at
>>> com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.processRequest(RemoteJmxConnectorServlet.java:109)
>>>
>>> at
>>> com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.doPost(RemoteJmxConnectorServlet.java:180)
>>>
>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:397)
>>>
>>> at
>>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:278)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:586)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:556)
>>>
>>> at
>>> org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:246)
>>>
>>> at
>>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:586)
>>>
>>> at
>>> com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
>>> at
>>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:586)
>>>
>>> at
>>> com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
>>>
>>> at
>>> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
>>> at
>>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:137)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:586)
>>>
>>> at
>>> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:556)
>>>
>>> at
>>> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
>>> at
>>> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:231)
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:619)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.processNonBlocked(DefaultProcessorTask.java:550)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:780)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:326)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:251)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:205)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
>>>
>>> at
>>> com.sun.enterprise.web.connector.grizzly.WorkerThreadImpl.run(WorkerThreadImpl.java:103)
>>>
>>> Caused by: com.sun.enterprise.admin.config.MBeanConfigException:
>>> Property password can not be removed.
>>> at
>>> com.sun.enterprise.admin.config.ManagedConfigBean.wrapAndThrowMBeanException(ManagedConfigBean.java:1599)
>>>
>>> at
>>> com.sun.enterprise.admin.config.ManagedConfigBean.setElementProperty(ManagedConfigBean.java:749)
>>>
>>> at
>>> com.sun.enterprise.admin.config.ManagedConfigBean.setProperty(ManagedConfigBean.java:698)
>>>
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:353)
>>>
>>> at
>>> com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:336)
>>>
>>> at
>>> com.sun.enterprise.admin.config.ManagedConfigBean.invokeOperation(ManagedConfigBean.java:1507)
>>>
>>> at
>>> com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:454)
>>>
>>> ... 62 more
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <!DOCTYPE resources PUBLIC
>>> "-//Sun Microsystems Inc.//DTD Application Server 9.0 Domain//EN"
>>> "/ws/sjsas90/publish/glassfish/lib/dtds/sun-resources_1_2.dtd">
>>> <resources>
>>> <jdbc-connection-pool allow-non-component-callers="true"
>>> name="mysql-pool" connection-validation-method="auto-commit"
>>>
>>> datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"
>>> fail-all-connections="false"
>>> idle-timeout-in-seconds="300"
>>> is-connection-validation-required="false"
>>> is-isolation-level-guaranteed="false" max-pool-size="32"
>>> max-wait-time-in-millis="60000"
>>> non-transactional-connections="false"
>>> pool-resize-quantity="2" res-type="javax.sql.DataSource"
>>> steady-pool-size="8">
>>> <property name="datasourceName" value="mysql"/>
>>> <property name="user" value="root"/>
>>> <property name="password" value=""/>
>>> <property name="port" value="3306"/>
>>> <property name="databaseName" value="test"/>
>>> <property name="serverName" value="localhost"/>
>>> </jdbc-connection-pool>
>>> <jdbc-resource enabled="true" pool-name="mysql-pool"
>>> jndi-name="jdbc/mysql"/>
>>> </resources>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>
>