-
1. Re: Anonymous beans
adrian.brock Apr 7, 2008 11:22 AM (in response to alesj)"alesj" wrote:
public Object clone() { AbstractBeanMetaData clone = new AbstractBeanMetaData(); doClone(clone); return clone; }
No you should use covariant return typespublic AbstractBeanMetaData clone() { ... }
protected void doClone(AbstractBeanMetaData clone) { super.doClone(clone); clone.setBean(bean); clone.setName(name); clone.setAliases(aliases); ... }
Why are you "cloning" fields that are direct referenes? What does it achieve?
Do we already have some similar code, to clone collections:@SuppressWarnings("unchecked") public static <U extends JBossInterface, T extends Collection<U>> T clone(T collection) { if (collection == null) return null; try { Class<? extends Collection> collectionClass = collection.getClass(); T clone = (T)collectionClass.newInstance(); for (U item : collection) clone.add((U)item.clone()); return clone; } catch (Throwable t) { throw new RuntimeException(t); } }
This looks overally complicated and an obvious misuse of generics again.
Why have generics then do all the casting and suppress warnings?
The way to clone collections is something like:Set<String> aliases = this.getAliases(); if (aliases != null) clone.setAliases(new HashSet<String>(aliases));
-
2. Re: Anonymous beans
alesj Apr 7, 2008 11:35 AM (in response to alesj)"adrian@jboss.org" wrote:
Why are you "cloning" fields that are direct referenes? What does it achieve?
You mean immutables?
Does Object::clone do that already for me?"adrian@jboss.org" wrote:
This looks overally complicated and an obvious misuse of generics again.
Why have generics then do all the casting and suppress warnings?
The way to clone collections is something like:Set<String> aliases = this.getAliases(); if (aliases != null) clone.setAliases(new HashSet<String>(aliases));
All would be fine if Object::getClass returned the right Class generic. :-)
I don't wanna do that extra 2 lines (null check and the new collection instantiation) for every cloning of the collection.
And I guess I would also have to iterate over all the collection items that are not immutable and clone them before adding them to new collection instance.
Another code that I don't want to duplicate. -
3. Re: Anonymous beans
alesj Apr 8, 2008 8:04 AM (in response to alesj)"alesj" wrote:
And I guess I would also have to iterate over all the collection items that are not immutable and clone them before adding them to new collection instance.
I need MetaDataVisitorNode to extend JBossInterface in order to clone AbstractCollectionMetaData and AbstractMapMetaData:public class AbstractCollectionMetaData extends AbstractTypeMetaData implements Collection<MetaDataVisitorNode>, Serializable { private static final long serialVersionUID = 2L; /** The collection */ protected List<MetaDataVisitorNode> collection = new ArrayList<MetaDataVisitorNode>(); ... public class AbstractMapMetaData extends AbstractTypeMetaData implements Map<MetaDataVisitorNode, MetaDataVisitorNode>, Serializable { private static final long serialVersionUID = 2L; /** The map */ private Map<MetaDataVisitorNode, MetaDataVisitorNode> map = new HashMap<MetaDataVisitorNode, MetaDataVisitorNode>();
So that I can iterate over the items and call item::clone(). -
4. Re: Anonymous beans
adrian.brock Apr 8, 2008 8:32 AM (in response to alesj)No. Just make MetaDataVisitorNode implement Cloneable.
-
5. Re: Anonymous beans
alesj Apr 8, 2008 8:45 AM (in response to alesj)"adrian@jboss.org" wrote:
No. Just make MetaDataVisitorNode implement Cloneable.
How does that help me with cloning the items?
Since the item::clone() method comes from Object, where it is protected.
e.g.public AbstractCollectionMetaData clone() { AbstractCollectionMetaData clone = (AbstractCollectionMetaData)super.clone(); clone.collection = getDefaultInstance(); for (MetaDataVisitorNode item : collection) clone.collection.add((MetaDataVisitorNode)item.clone()); return clone; }
-
6. Re: Anonymous beans
brian.stansberry Apr 11, 2008 12:12 AM (in response to alesj)There's a problem with the way the anonymous bean impl (NestedBeanHandler I think) is generating names. Looks like it's getting confused about where it is in the nested bean hierarchy and ends up trying to apply the same name to multiple beans.
The -beans.xml I'm trying to deploy can be found at https://svn.jboss.org/repos/jbossas/trunk/cluster/src/etc/jboss-cache-manager-beans.xml . When I try to deploy it in AS trunk I get this:2008-04-10 22:45:20,150 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] (main) Error installing to Real: name=vfsfile:/home/bes/dev/jboss/trunk/build/output/jboss-5.0.0.CR1/server/all/deploy/cluster/jboss-cache-manager-beans.xml state=PreReal mode=Manual requiredState=Real org.jboss.deployers.spi.DeploymentException: Error deploying: CacheConfigurationRegistry$runtimeConfig at org.jboss.deployers.spi.DeploymentException.rethrowAsDeploymentException(DeploymentException.java:49) at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:92) at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:46) at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62) at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50) at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:174) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:970) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:991) at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:911) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1394) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:786) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:914) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:836) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:674) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:456) at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:594) at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:541) at org.jboss.system.server.profileservice.ProfileServiceBootstrap.loadProfile(ProfileServiceBootstrap.java:259) at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:137) at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:409) at org.jboss.Main.boot(Main.java:209) at org.jboss.Main$1.run(Main.java:544) at java.lang.Thread.run(Thread.java:595) Caused by: java.lang.IllegalStateException: CacheConfigurationRegistry$runtimeConfig is already installed. at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:577) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:443) at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:88) ... 22 more
Note that the runtimeConfig property is not an immediate child of the CacheConfigurationRegistry bean. It's a property of "StandardSessionCacheConfig" and "FieldSessionCacheConfig".
To add to the challenge, "StandardSessionCacheConfig" and "FieldSessionCacheConfig" really can be anonymous. I just gave them names for human readability. So any solution should work even if they were anonymous.
BTW, what I'm trying to do in the part of this file that uses anonymous beans is parse XML to create a set of JBoss Cache configurations. JBC has its own XML format and parser that I can use to accomplish this. It didn't have system property substitution, but I added that earlier this week. So I can use that. I'd prefer to use MC to do this. But don't let me totally rearrange your schedule; I have a workaround. -
7. Re: Anonymous beans
alesj Apr 11, 2008 4:14 AM (in response to alesj)Ah, I see.
Looks like I've tried to be too user friendly.
I'll fix this in NestedBeanHandler, adding counter to inner beans that come from property as well.
But if someone wants that user friendly generated names, one can override the AbstractBeanMetaData::createNestedBeanHandler, providing custom NestedBeanHandler::generateName.