Arquillian Chameleon - trouble to run container in managed manual mode


#1

Hi,

I found out the Arquillian project Chameleon and it would be really handy for me. I started to experiment with it but I’ve got stuck at place where I need to run managed container in manual mode.

I found out that there is some trouble with getting container configuration properties from registry in ClientContainerController.

At first when container is initialized with Chameleon properties of delegate are precisely those that are set up in my arquillian.xml (https://github.com/arquillian/arquillian-container-chameleon/blob/master/src/main/java/org/arquillian/container/chameleon/ChameleonContainer.java#L166)

But as I use the ContainerController.start(String containerQualifier, Map<String, String> config) there is called setup container once again (https://github.com/arquillian/arquillian-core/blob/master/container/test-impl-base/src/main/java/org/jboss/arquillian/container/test/impl/client/container/ClientContainerController.java#L149) and at that point the properties of the container that is drawn from registry are empty. Which means that container would start but with incorrect settings.

Is there way how to set up Chameleon or Arquillian to process this correctly? Or if it’s a bug is it possible to fix it?

Thanks a lot
Ondra


#2

Nice! Yeah, didn’t consider or test that usecase yet, but from the sound of it it will be fixed via this issue:

Essentially in Alpha1 we assumed Chameleon would be the main Container and removed the Target Container configuration from the Registry for to pass it in the backway… But that had some issues for Cube, and now this… so I’m changing it to remove the Chameleon config instead and pass those of in the background…

Give me a few hours to code up the last pieces here and I’ll push to master.


#3

The issue is now in upstream/master and I’ve pushed a new 1.0.0.Final-SNAPSHOT to the jboss-nexus repositories if you want to take it for a spin and see if this fixes the problem. (or just build it locally)


#4

Thanks a lot for the fix. I really appreciate that!

It really helps but partially. I’ve got another trouble here :smile:

First I needed to do a small change during container initialization. I don’t know what event triggers the second initalization of the chameleon container but it’s similar to the previous problem. There is missing configuration of chameleon properties (chameleonTarget). I solved it in this way:


Just I’m not sure if it’s correct fix. What do you think about this?

After that I’ve got into kind of class loader hell.
My scenario is to running two containers - EAP6 and WildFly(EAP7) as mentioned in manual mode where I start them and stop them arbitrarily. Before the deployment is done I use ServerTask extension and ManagementClient do setup containers (https://github.com/wildfly/wildfly-arquillian/blob/master/common/src/main/java/org/jboss/as/arquillian/container/ManagementClient.java). But the ManagementClient implementation differs in incompatible way between WildFly and EAP6 - mainly EAP6 has got subsystem web and WFLY has got subsystem undertow.

As my tests uses ManagementClient I need to have the artifact - e.g. wildfly-arquillian-container-managed during compilation. I use Maven and I haven’t found way how to get using an artifact during compilation but not passing it to test classpath.
The result is that artifact wildfly-arquillian-container-managed is defined in pom.xml, EAP6 delegate container loads jboss-as-arquillian-container-managed but when ManagementClient is needed to be used for EAP6 then it’s loaded from parent class loader (meaning from wildfly-arquillian-container-managed). I’ve started with wild hacking to get loaded class first from the URLClassLoader and then from parent ones. But it does not seem as correct solution.
Don’t you have some idea about this?

I can see one possible way to not using ServerSetupTask at all https://github.com/wildfly/wildfly-arquillian/blob/master/common/src/main/java/org/jboss/as/arquillian/api/ServerSetupTask.java and does not touch ManagementClient. But my testsuite uses them quite heavily and I’m not happy with such move. What do you think here. Would you see some way how to manage this?

Thanks a lot


#5

Chameleon currently hides all of the target container and only loads/register a very limited version of it.

So technically anything that the Container expose should be available, but none of the extra Observers/services will be. Meaning the Container will produce a ManagementClient, but there is no Service registered to inject that into the test. (and of course also the fact that it’s not really available on classpath.) ServerSetupTasks will not work.

What specifically do you want the ManagementClient for?


#6

Created #14 for the support of manual containers; https://github.com/arquillian/arquillian-container-chameleon/issues/14


#7

I see. Thanks again for the fix (#14).

I use the ManagementClient in the same way how it’s used in WildFly testsuite (e.g. https://github.com/wildfly/wildfly/blob/master/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/mdb/containerstart/SendMessagesTestCase.java#L126). ManagementClient is used to run CLI commands to set the server.
ServerSetup task is used to initialize container before deployment and ManagementClient is used to provide the configuration. Configuration is then cleared on undeployment.

I understand the issue of container specific injection. Nevertheless I would like clarify if you think there is chance to provide container specific injections to tests/extensions? Or this is not planned feature for Chameleon? Thanks.


#8

Hi Aslak,

I have been thining about changes that I need to do in my testsuite and I understand that I can’t expect to get injected ManagementClient (or other jboss specific classes) to my extension.

But I still wonder if current class loading management is right. My point is that version of implementation defined in yaml should get precedence over anyone defined as dependency of the test project or not? I mean it would be handy to have classloader which does not delegate loading directly to parent but it tries to load it first at its level. My naive implementation is this: [ochaloup/arquillian-container-chameleon] class loader hacking

What do you think?


#9

Hi,

I’m back here again with my doubt about class loading precedence. I have still trouble with it.

Currently the is use URLClassLoader which delegates class loading to parent class loader. As the yaml configuration defines precise versions of the library should not be used altered classloader which starts loading from jars defined in yaml?


#10

This might not be exactly what you’re looking for, but it’s possible to access the individual target containers ManagementClient without having any of the adapters on application classpath.

The target containers started by Chameleon does their normal context sharing, so we can access e.g. ManagementClient via the DeploymentContext with some hackery since we don’t actually have the ManagementClient from e.g. WIldFly on application classpath.

  • Create a local v of the ManagementClient class and expose the methods needed
  • Register a ResourceProvider that can proxy from the local ManagementClient to the target client as needed based on current active context
  • You can now use the local ManagementClient as you see fit in the context of any of the Deployments

This rely on this Chameleon branch to work: https://github.com/arquillian/arquillian-container-chameleon/tree/expose_target_cl


#11

Hi Aslak,

I’m sorry for delay in answering. I haven’t got time to continue working on my multi container testcase. Now I’m back on this task and I need to finish it :wink:

Thanks a lot for your branch!
I’ve started to implement changes which I need for Chameleon to work in my testsuite. I’m not finished yet but the my current progress seems nice. Now the management client is loaded from proper container as its dependency.
I hope that I finish my effor till end of the week to report back the outcome.

Nevertheless I have a minor question for Arquillian in general. Do I have some chance to inject the created proxy ManagementClient object to another extension?

I mean previously I have used following injection in my extension

@Inject
private Instance<ManagementClient> managementClient;

that does not work with my newly created ManagementClient interface. As far as I understand I can’t use @ArquillianResource which is aimed to be used in TestCase. Is there chance to propagate the proxy ManagementClient to Instance of another extension?

Plus I would like ask if you plan to merge your changes from branch expose_target_cl to master and so if I will be able to use this feature in next Chameleon release.

Thanks again
Ondra


#12

Yes, you could move the creation of the proxy to ‘somewhere’ else then then the ResourceProvider. One option I think should work is to create an @Observer of e…g BeforeStart, then create the Proxy and produce it in there via @ContainerScoped InstanceProducer<ManagementClinetProxy> proxy; proxy.set(createInstnace()).

That would allow others to @Inject Instance<ManagementClinetProxy>.

Roughly something like:

public class TestExtension implements LoadableExtension {
  
  public register(ExtensionBuilder builder) {
     builder.observer(MgmClientProxyCreator.class);
  }

  pubic static class MgmClientProxyCreator {
    @Inject @ContainerScoped
    private InstanceProducer<ManagementClientProxy> producer;
    public void create(@Observes BeforeStart event) {
      producer.set(createProxy());
    }
  }
}

Then in the ResourceProvider you would just @Inject the Instance<ManagementClientProxy> and return that.

Yea, just wanted to see if you would find it useful or not first :smile:


#13

Hi Aslak,

I’ve reworked my testsuite and I can confirm that Chameleon works for me nicely now. Thanks.

And thank you for the instance producer code. It solves my issue with injection of the proxy of management client to my other extensions.

In summary it seems that all my troubles are solved and my testsuite is running seamlessly :wink:
:+1:
Ondra


#14

@ochaloup Good news! Are you relying on the changes in the Chameleon expose_target_cl branch?


#15

@aslak hi, yeap, I’m using the expose_target_cl branch currently in my testcase


#16

Ok, I’ll get it upstream


#17

Nice! Thank you. Looking forward to beta :smile:


#18

@ochaloup Sorry, no Beta, but Alpha5 is out :smile:
http://arquillian.org/blog/2015/09/16/arquillian-container-chameleon-1-0-0-Alpha5/


#19

OK :slight_smile: Nevertheless thank you for all the fixes.