-
1. Re: ClassLoadingAdmin
alesj Mar 2, 2010 4:26 PM (in response to adrian.brock)Found a potential NPE -- see Module class:
public static boolean resolveModules(Module... modules) throws Exception { if (modules == null || modules.length == 0) return true; LifeCycle[] lifeCycles = new LifeCycle[modules.length]; for (int i = 0; i < modules.length; ++i) { Module module = modules[i]; if (module == null) throw new IllegalArgumentException("Null module"); LifeCycle lifeCycle = module.getLifeCycle(); if (lifeCycle == null) log.warn(module + " has no lifecycle, don't know how to resolve it."); lifeCycles[i] = lifeCycle; // HERE -- we allow null } lifeCycles[0].resolve(lifeCycles); // NPE #1 for (LifeCycle lifeCycle : lifeCycles) { if (lifeCycle.isResolved() == false) // NPE#2 return false; } return true; }
And the code in #1 and #2 looks a lot the same -- could be made into one?
-
2. Re: ClassLoadingAdmin
adrian.brock Mar 4, 2010 6:21 AM (in response to alesj)I fixed the NPE by throwing an error.
I could maybe change the LifeCycle.resolve() methods to return a boolean saying whether the resolve actually worked or not?
-
3. Re: ClassLoadingAdmin
thomas.diesler Mar 4, 2010 8:23 AM (in response to adrian.brock)Eventually we will need a notion of try run for module resolution. The concept of application also needs to be supported - not sure if this can aleady be done by the Module abstraction.
The use case is:
From a gui select the application located at some repository to download/install into the framework.
An application consists of potentially very many bundles.
Try run the resolver using the application metadata.
Only when the application can be resolved in the running framework, do the install.
The worst case, which must be avoided is a partial install that fails and leaves the framework in a state where random bits are installed/resolved that cannot easily been uninstalled. Essentially, the resolve step for a set of bundles must be atomic.
-
4. Re: ClassLoadingAdmin
alesj Mar 4, 2010 8:16 AM (in response to adrian.brock)I could maybe change the LifeCycle.resolve() methods to return a boolean saying whether the resolve actually worked or not?
If this changes the need to do resolving check twice, sure.
btw, I find it a bit strange to see lifeCycles[0].resolve(lifeCycles). :-)
-
5. Re: ClassLoadingAdmin
alesj Mar 4, 2010 8:38 AM (in response to thomas.diesler)From a gui select the application located at some repository to download/install into the framework.
An application consists of potentially very many bundles.
Try run the resolver using the application metadata.
Only when the application can be resolved in the running framework, do the install.
The worst case, which must be avoided is a partial install that fails and leaves the framework in a state where random bits are installed/resolved that cannot easily been uninstalled. Essentially, the resolve step for a set of bundles must be atomic.
This sounds more like a job for ProfileService.
As it's the only one that knows which deployments/repositories exist that could potentially resolve this -- aka dry resolve.
MC's mechanism should only know to say true or false if a particular set of ControllerContexts can be resolved.
Although I don't see how we could do dry resolve atm != deploy+undeploy if not complete.
-
6. Re: ClassLoadingAdmin
adrian.brock Mar 4, 2010 8:46 AM (in response to alesj)alesj wrote:
btw, I find it a bit strange to see lifeCycles[0].resolve(lifeCycles). :-)
That's what gives it the chance to do width first resolution.
If you look at the DeploymentLifecycle implementation,
it will fallback to doing it one at a time if the lifecycles have mixed implementations
since it can't handle that case width first.
-
7. Re: ClassLoadingAdmin
adrian.brock Mar 4, 2010 8:55 AM (in response to thomas.diesler)thomas.diesler@jboss.com wrote:
The use case is:
From a gui select the application located at some repository to download/install into the framework.
An application consists of potentially very many bundles.
Try run the resolver using the application metadata.
Only when the application can be resolved in the running framework, do the install.
The worst case, which must be avoided is a partial install that fails and leaves the framework in a state where random bits are installed/resolved that cannot easily been uninstalled. Essentially, the resolve step for a set of bundles must be atomic.
You can already do that.
deploy/change(deploymentNames);
try
{
checkComplete(deploymentNames);
}
catch (IncompleteDeploymentException e)
{
undeploy/change[back](deploymentNames);
}
One of the features I added (different to what happens in 4.2.x) is that if a subdeployment ends
up in the error state then so does the rest of the application (i.e. top level deployment, subdeployments and components).
NOTE: It is still an unimplemented feature in the profile service to be able to "dry run" an install.
i.e. you can validate the metadata can be parsed and is complete and check all the dependencies
without creating the actual runtime objects.
Of course there might still be runtime errors thrown from the objects themselves, which this wouldn't catch.
-
8. Re: ClassLoadingAdmin
emuckenhuber Mar 4, 2010 9:02 AM (in response to adrian.brock)adrian@jboss.org wrote:
NOTE: It is still an unimplemented feature in the profile service to be able to "dry run" an install.
i.e. you can validate the metadata can be parsed and is complete and check all the dependencies
without creating the actual runtime objects.
Of course there might still be runtime errors thrown from the objects themselves, which this wouldn't catch.
You mean doing mainDeployer.change(deployment, PRE_REAL) ?
-
9. Re: ClassLoadingAdmin
adrian.brock Mar 4, 2010 9:07 AM (in response to emuckenhuber)emuckenhuber wrote:
adrian@jboss.org wrote:
NOTE: It is still an unimplemented feature in the profile service to be able to "dry run" an install.
i.e. you can validate the metadata can be parsed and is complete and check all the dependencies
without creating the actual runtime objects.
Of course there might still be runtime errors thrown from the objects themselves, which this wouldn't catch.
You mean doing mainDeployer.change(deployment, PRE_REAL) ?
No. I mean having a special copy of the kernel/deployers in the management client that doesn't do any of the callbacks for the real deployments.
So it will go through the dependency resolution, but won't invoke constructors, set properties, etc.