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).
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