use of org.apache.openejb.loader.SystemInstance in project tomee by apache.
the class Assembler method buildContainerSystem.
// ///////////////////////////////////////////////////////////////////
// //
// // Public Methods Used for Assembly
// //
// ///////////////////////////////////////////////////////////////////
/**
* When given a complete OpenEjbConfiguration graph this method
* will construct an entire container system and return a reference to that
* container system, as ContainerSystem instance.
*
* This method leverage the other assemble and apply methods which
* can be used independently.
*
* Assembles and returns the {@link CoreContainerSystem} using the
* information from the {@link OpenEjbConfiguration} object passed in.
* <pre>
* This method performs the following actions(in order):
*
* 1 Assembles ProxyFactory
* 2 Assembles External JNDI Contexts
* 3 Assembles TransactionService
* 4 Assembles SecurityService
* 5 Assembles ConnectionManagers
* 6 Assembles Connectors
* 7 Assembles Containers
* 8 Assembles Applications
* </pre>
*
* @param configInfo OpenEjbConfiguration
* @throws Exception if there was a problem constructing the ContainerSystem.
* @see OpenEjbConfiguration
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public void buildContainerSystem(final OpenEjbConfiguration configInfo) throws Exception {
final SystemInstance systemInstance = SystemInstance.get();
if (systemInstance.getOptions().get(OPENEJB_JPA_DEPLOY_TIME_ENHANCEMENT_PROP, false)) {
systemInstance.addObserver(new DeployTimeEnhancer());
}
if (hasBatchEE()) {
systemInstance.addObserver(new BatchEEServiceManager());
}
for (final ServiceInfo serviceInfo : configInfo.facilities.services) {
createService(serviceInfo);
}
final ContainerSystemInfo containerSystemInfo = configInfo.containerSystem;
if (configInfo.facilities.intraVmServer != null) {
createProxyFactory(configInfo.facilities.intraVmServer);
}
for (final JndiContextInfo contextInfo : configInfo.facilities.remoteJndiContexts) {
createExternalContext(contextInfo);
}
createTransactionManager(configInfo.facilities.transactionService);
createSecurityService(configInfo.facilities.securityService);
final Set<String> reservedResourceIds = new HashSet<>(configInfo.facilities.resources.size());
for (final AppInfo appInfo : containerSystemInfo.applications) {
reservedResourceIds.addAll(appInfo.resourceIds);
}
final Map<AppInfo, ClassLoader> appInfoClassLoaders = new HashMap<>();
final Map<String, ClassLoader> appClassLoaders = new HashMap<>();
for (final AppInfo appInfo : containerSystemInfo.applications) {
appInfoClassLoaders.put(appInfo, createAppClassLoader(appInfo));
appClassLoaders.put(appInfo.appId, createAppClassLoader(appInfo));
}
final Set<String> rIds = new HashSet<>(configInfo.facilities.resources.size());
for (final ResourceInfo resourceInfo : configInfo.facilities.resources) {
createResource(configInfo.facilities.services, resourceInfo);
rIds.add(resourceInfo.id);
}
rIds.removeAll(reservedResourceIds);
final ContainerSystem component = systemInstance.getComponent(ContainerSystem.class);
if (component != null) {
postConstructResources(rIds, ParentClassLoaderFinder.Helper.get(), component.getJNDIContext(), null);
} else {
throw new RuntimeException("ContainerSystem has not been initialzed");
}
// Containers - create containers using the application's classloader
final Map<String, List<ContainerInfo>> appContainers = new HashMap<>();
for (final ContainerInfo serviceInfo : containerSystemInfo.containers) {
List<ContainerInfo> containerInfos = appContainers.computeIfAbsent(serviceInfo.originAppName, k -> new ArrayList<>());
containerInfos.add(serviceInfo);
}
for (final Entry<String, List<ContainerInfo>> stringListEntry : appContainers.entrySet()) {
final List<ContainerInfo> containerInfos = stringListEntry.getValue();
final ClassLoader classLoader = appClassLoaders.get(stringListEntry.getKey());
final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
if (classLoader != null) {
Thread.currentThread().setContextClassLoader(classLoader);
}
for (final ContainerInfo containerInfo : containerInfos) {
createContainer(containerInfo);
}
} finally {
Thread.currentThread().setContextClassLoader(oldCl);
}
}
// before any deployment bind global to be able to share the same context
createJavaGlobal();
for (final AppInfo appInfo : containerSystemInfo.applications) {
try {
// use the classloader from the map above
createApplication(appInfo, appInfoClassLoaders.get(appInfo));
} catch (final DuplicateDeploymentIdException e) {
// already logged.
} catch (final Throwable e) {
logger.error("appNotDeployed", e, appInfo.path);
final DeploymentExceptionManager exceptionManager = systemInstance.getComponent(DeploymentExceptionManager.class);
if (exceptionManager != null && e instanceof Exception) {
exceptionManager.saveDeploymentException(appInfo, (Exception) e);
}
}
}
systemInstance.fireEvent(new ContainerSystemPostCreate());
}
use of org.apache.openejb.loader.SystemInstance in project tomee by apache.
the class Assembler method createApplication.
private AppContext createApplication(final AppInfo appInfo, ClassLoader classLoader, final boolean start) throws OpenEJBException, IOException, NamingException {
try {
try {
mergeServices(appInfo);
} catch (final URISyntaxException e) {
logger.info("Can't merge resources.xml services and appInfo.properties");
}
// The path is used in the UrlCache, command line deployer, JNDI name templates, tomcat integration and a few other places
if (appInfo.appId == null) {
throw new IllegalArgumentException("AppInfo.appId cannot be null");
}
if (appInfo.path == null) {
appInfo.path = appInfo.appId;
}
Extensions.addExtensions(classLoader, appInfo.eventClassesNeedingAppClassloader);
logger.info("createApplication.start", appInfo.path);
final Context containerSystemContext = containerSystem.getJNDIContext();
// To start out, ensure we don't already have any beans deployed with duplicate IDs. This
// is a conflict we can't handle.
final List<String> used = getDuplicates(appInfo);
if (used.size() > 0) {
StringBuilder message = new StringBuilder(logger.error("createApplication.appFailedDuplicateIds", appInfo.path));
for (final String id : used) {
logger.error("createApplication.deploymentIdInUse", id);
message.append("\n ").append(id);
}
throw new DuplicateDeploymentIdException(message.toString());
}
final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
for (final ContainerInfo container : appInfo.containers) {
createContainer(container);
}
} finally {
Thread.currentThread().setContextClassLoader(oldCl);
}
// Construct the global and app jndi contexts for this app
final InjectionBuilder injectionBuilder = new InjectionBuilder(classLoader);
final Set<Injection> injections = new HashSet<>();
injections.addAll(injectionBuilder.buildInjections(appInfo.globalJndiEnc));
injections.addAll(injectionBuilder.buildInjections(appInfo.appJndiEnc));
final JndiEncBuilder globalBuilder = new JndiEncBuilder(appInfo.globalJndiEnc, injections, appInfo.appId, null, GLOBAL_UNIQUE_ID, classLoader, appInfo.properties);
final Map<String, Object> globalBindings = globalBuilder.buildBindings(JndiEncBuilder.JndiScope.global);
final Context globalJndiContext = globalBuilder.build(globalBindings);
final JndiEncBuilder appBuilder = new JndiEncBuilder(appInfo.appJndiEnc, injections, appInfo.appId, null, appInfo.appId, classLoader, appInfo.properties);
final Map<String, Object> appBindings = appBuilder.buildBindings(JndiEncBuilder.JndiScope.app);
final Context appJndiContext = appBuilder.build(appBindings);
final boolean cdiActive = shouldStartCdi(appInfo);
try {
// Generate the cmp2/cmp1 concrete subclasses
final CmpJarBuilder cmpJarBuilder = new CmpJarBuilder(appInfo, classLoader);
final File generatedJar = cmpJarBuilder.getJarFile();
if (generatedJar != null) {
classLoader = ClassLoaderUtil.createClassLoader(appInfo.path, new URL[] { generatedJar.toURI().toURL() }, classLoader);
}
final AppContext appContext = new AppContext(appInfo.appId, SystemInstance.get(), classLoader, globalJndiContext, appJndiContext, appInfo.standaloneModule);
for (final Entry<Object, Object> entry : appInfo.properties.entrySet()) {
if (!Module.class.isInstance(entry.getValue())) {
appContext.getProperties().put(entry.getKey(), entry.getValue());
}
}
appContext.getInjections().addAll(injections);
appContext.getBindings().putAll(globalBindings);
appContext.getBindings().putAll(appBindings);
containerSystem.addAppContext(appContext);
appContext.set(AsynchronousPool.class, AsynchronousPool.create(appContext));
final Map<String, LazyValidatorFactory> lazyValidatorFactories = new HashMap<>();
final Map<String, LazyValidator> lazyValidators = new HashMap<>();
final boolean isGeronimo = SystemInstance.get().hasProperty("openejb.geronimo");
// try to not create N times the same validator for a single app
final Map<ComparableValidationConfig, ValidatorFactory> validatorFactoriesByConfig = new HashMap<>();
if (!isGeronimo) {
// Bean Validation
// ValidatorFactory needs to be put in the map sent to the entity manager factory
// so it has to be constructed before
final List<CommonInfoObject> vfs = listCommonInfoObjectsForAppInfo(appInfo);
final Map<String, ValidatorFactory> validatorFactories = new HashMap<>();
for (final CommonInfoObject info : vfs) {
if (info.validationInfo == null) {
continue;
}
final ComparableValidationConfig conf = new ComparableValidationConfig(info.validationInfo.providerClassName, info.validationInfo.messageInterpolatorClass, info.validationInfo.traversableResolverClass, info.validationInfo.constraintFactoryClass, info.validationInfo.parameterNameProviderClass, info.validationInfo.version, info.validationInfo.propertyTypes, info.validationInfo.constraintMappings, info.validationInfo.executableValidationEnabled, info.validationInfo.validatedTypes);
ValidatorFactory factory = validatorFactoriesByConfig.get(conf);
if (factory == null) {
try {
// lazy cause of CDI :(
final LazyValidatorFactory handler = new LazyValidatorFactory(classLoader, info.validationInfo);
factory = (ValidatorFactory) Proxy.newProxyInstance(appContext.getClassLoader(), VALIDATOR_FACTORY_INTERFACES, handler);
lazyValidatorFactories.put(info.uniqueId, handler);
} catch (final ValidationException ve) {
logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
continue;
}
validatorFactoriesByConfig.put(conf, factory);
} else {
lazyValidatorFactories.put(info.uniqueId, LazyValidatorFactory.class.cast(Proxy.getInvocationHandler(factory)));
}
validatorFactories.put(info.uniqueId, factory);
}
// validators bindings
for (final Entry<String, ValidatorFactory> validatorFactory : validatorFactories.entrySet()) {
final String id = validatorFactory.getKey();
final ValidatorFactory factory = validatorFactory.getValue();
try {
containerSystemContext.bind(VALIDATOR_FACTORY_NAMING_CONTEXT + id, factory);
final Validator validator;
try {
final LazyValidator lazyValidator = new LazyValidator(factory);
validator = (Validator) Proxy.newProxyInstance(appContext.getClassLoader(), VALIDATOR_INTERFACES, lazyValidator);
lazyValidators.put(id, lazyValidator);
} catch (final Exception e) {
logger.error(e.getMessage(), e);
continue;
}
containerSystemContext.bind(VALIDATOR_NAMING_CONTEXT + id, validator);
} catch (final NameAlreadyBoundException e) {
throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
} catch (final Exception e) {
throw new OpenEJBException(e);
}
}
validatorFactories.clear();
}
// JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
// to the class loader which must be added before any classes are loaded
final Map<String, String> units = new HashMap<>();
final PersistenceBuilder persistenceBuilder = new PersistenceBuilder(persistenceClassLoaderHandler);
for (final PersistenceUnitInfo info : appInfo.persistenceUnits) {
final ReloadableEntityManagerFactory factory;
try {
factory = persistenceBuilder.createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig, cdiActive);
containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + info.id);
} catch (final NameAlreadyBoundException e) {
throw new OpenEJBException("PersistenceUnit already deployed: " + info.persistenceUnitRootUrl);
} catch (final Exception e) {
throw new OpenEJBException(e);
}
factory.register();
}
logger.debug("Loaded persistence units: " + units);
// Connectors
for (final ConnectorInfo connector : appInfo.connectors) {
final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
// todo add undeployment code for these
if (connector.resourceAdapter != null) {
createResource(null, connector.resourceAdapter);
}
for (final ResourceInfo outbound : connector.outbound) {
createResource(null, outbound);
// set it after as a marker but not as an attribute (no getOpenejb().setConnector(...))
outbound.properties.setProperty("openejb.connector", "true");
}
for (final MdbContainerInfo inbound : connector.inbound) {
createContainer(inbound);
}
for (final ResourceInfo adminObject : connector.adminObject) {
createResource(null, adminObject);
}
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
}
final List<BeanContext> allDeployments = initEjbs(classLoader, appInfo, appContext, injections, new ArrayList<>(), null);
if ("true".equalsIgnoreCase(SystemInstance.get().getProperty(PROPAGATE_APPLICATION_EXCEPTIONS, appInfo.properties.getProperty(PROPAGATE_APPLICATION_EXCEPTIONS, "false")))) {
propagateApplicationExceptions(appInfo, classLoader, allDeployments);
}
if (cdiActive) {
new CdiBuilder().build(appInfo, appContext, allDeployments);
ensureWebBeansContext(appContext);
appJndiContext.bind("app/BeanManager", appContext.getBeanManager());
appContext.getBindings().put("app/BeanManager", appContext.getBeanManager());
} else {
// ensure we can reuse it in tomcat to remove OWB filters
appInfo.properties.setProperty("openejb.cdi.activated", "false");
}
// now cdi is started we can try to bind real validator factory and validator
if (!isGeronimo) {
for (final Entry<String, LazyValidator> lazyValidator : lazyValidators.entrySet()) {
final String id = lazyValidator.getKey();
final ValidatorFactory factory = lazyValidatorFactories.get(lazyValidator.getKey()).getFactory();
try {
final String factoryName = VALIDATOR_FACTORY_NAMING_CONTEXT + id;
containerSystemContext.unbind(factoryName);
containerSystemContext.bind(factoryName, factory);
final String validatoryName = VALIDATOR_NAMING_CONTEXT + id;
try {
// do it after factory cause of TCKs which expects validator to be created later
final Validator val = lazyValidator.getValue().getValidator();
containerSystemContext.unbind(validatoryName);
containerSystemContext.bind(validatoryName, val);
} catch (final Exception e) {
logger.error(e.getMessage(), e);
}
} catch (final NameAlreadyBoundException e) {
throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
} catch (final Exception e) {
throw new OpenEJBException(e);
}
}
}
startEjbs(start, allDeployments);
// App Client
for (final ClientInfo clientInfo : appInfo.clients) {
// determine the injections
final List<Injection> clientInjections = injectionBuilder.buildInjections(clientInfo.jndiEnc);
// build the enc
final JndiEncBuilder jndiEncBuilder = new JndiEncBuilder(clientInfo.jndiEnc, clientInjections, "Bean", clientInfo.moduleId, null, clientInfo.uniqueId, classLoader, new Properties());
// then, we can set the client flag
if (clientInfo.remoteClients.size() > 0 || clientInfo.localClients.size() == 0) {
jndiEncBuilder.setClient(true);
}
jndiEncBuilder.setUseCrossClassLoaderRef(false);
final Context context = jndiEncBuilder.build(JndiEncBuilder.JndiScope.comp);
// Debug.printContext(context);
containerSystemContext.bind("openejb/client/" + clientInfo.moduleId, context);
if (clientInfo.path != null) {
context.bind("info/path", clientInfo.path);
}
if (clientInfo.mainClass != null) {
context.bind("info/mainClass", clientInfo.mainClass);
}
if (clientInfo.callbackHandler != null) {
context.bind("info/callbackHandler", clientInfo.callbackHandler);
}
context.bind("info/injections", clientInjections);
for (final String clientClassName : clientInfo.remoteClients) {
containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
}
for (final String clientClassName : clientInfo.localClients) {
containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
logger.getChildLogger("client").info("createApplication.createLocalClient", clientClassName, clientInfo.moduleId);
}
}
// WebApp
final SystemInstance systemInstance = SystemInstance.get();
final WebAppBuilder webAppBuilder = systemInstance.getComponent(WebAppBuilder.class);
if (webAppBuilder != null) {
webAppBuilder.deployWebApps(appInfo, classLoader);
}
if (start) {
final EjbResolver globalEjbResolver = systemInstance.getComponent(EjbResolver.class);
globalEjbResolver.addAll(appInfo.ejbJars);
}
// bind all global values on global context
bindGlobals(appContext.getBindings());
validateCdiResourceProducers(appContext, appInfo);
// deploy MBeans
for (final String mbean : appInfo.mbeans) {
deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId);
}
for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
for (final String mbean : ejbJarInfo.mbeans) {
deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, ejbJarInfo.moduleName);
}
}
for (final ConnectorInfo connectorInfo : appInfo.connectors) {
for (final String mbean : connectorInfo.mbeans) {
deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId + ".add-lib");
}
}
postConstructResources(appInfo.resourceIds, classLoader, containerSystemContext, appContext);
deployedApplications.put(appInfo.path, appInfo);
resumePersistentSchedulers(appContext);
systemInstance.fireEvent(new AssemblerAfterApplicationCreated(appInfo, appContext, allDeployments));
logger.info("createApplication.success", appInfo.path);
// required by spec EE.5.3.4
if (setAppNamingContextReadOnly(allDeployments)) {
logger.info("createApplication.naming", appInfo.path);
}
return appContext;
} catch (final ValidationException | DeploymentException ve) {
throw ve;
} catch (final Throwable t) {
try {
destroyApplication(appInfo);
} catch (final Exception e1) {
logger.debug("createApplication.undeployFailed", e1, appInfo.path);
}
throw new OpenEJBException(messages.format("createApplication.failed", appInfo.path), t);
}
} finally {
// cleanup there as well by safety cause we have multiple deployment mode (embedded, tomcat...)
for (final WebAppInfo webApp : appInfo.webApps) {
appInfo.properties.remove(webApp);
}
}
}
use of org.apache.openejb.loader.SystemInstance in project tomee by apache.
the class LazyEjbReference method getObject.
public Object getObject() throws NamingException {
if (reference != null) {
return reference.getObject();
}
final SystemInstance systemInstance = SystemInstance.get();
final EjbResolver resolver = systemInstance.getComponent(EjbResolver.class);
final String deploymentId = resolver.resolve(info, moduleUri);
if (deploymentId == null) {
String key = "lazyEjbRefNotResolved";
if (info.getHome() != null) {
key += ".home";
}
final String message = messages.format(key, info.getName(), info.getEjbLink(), info.getHome(), info.getInterface());
throw new NameNotFoundException(message);
}
final ContainerSystem containerSystem = systemInstance.getComponent(ContainerSystem.class);
final BeanContext beanContext = containerSystem.getBeanContext(deploymentId);
if (beanContext == null) {
final String message = messages.format("deploymentNotFound", info.getName(), deploymentId);
throw new NameNotFoundException(message);
}
InterfaceType type = null;
switch(info.getRefType()) {
case LOCAL:
type = InterfaceType.BUSINESS_LOCAL;
break;
case REMOTE:
type = InterfaceType.BUSINESS_REMOTE;
break;
}
final String jndiName = "openejb/Deployment/" + JndiBuilder.format(deploymentId, info.getInterface(), type);
if (useCrossClassLoaderRef && isRemote(beanContext)) {
reference = new CrossClassLoaderJndiReference(jndiName);
} else {
reference = new IntraVmJndiReference(jndiName);
}
return reference.getObject();
}
use of org.apache.openejb.loader.SystemInstance in project tomee by apache.
the class OptimizedLoaderService method isFiltered.
// mainly intended to avoid conflicts between internal and overrided spec extensions
private boolean isFiltered(final Collection<Extension> extensions, final Extension next) {
final ClassLoader containerLoader = ParentClassLoaderFinder.Helper.get();
final Class<? extends Extension> extClass = next.getClass();
final String name = extClass.getName();
final String activeKey = name + ".active";
final SystemInstance systemInstance = SystemInstance.get();
if (!is(activeKey, config, systemInstance.getProperties(), "true")) {
return true;
}
switch(name) {
case "org.apache.geronimo.microprofile.openapi.cdi.GeronimoOpenAPIExtension":
return true;
case "org.apache.bval.cdi.BValExtension":
for (final Extension e : extensions) {
final String en = e.getClass().getName();
// org.hibernate.validator.internal.cdi.ValidationExtension but allowing few evolutions of packages
if (en.startsWith("org.hibernate.validator.") && en.endsWith("ValidationExtension")) {
log.info("Skipping BVal CDI integration cause hibernate was found in the application");
return true;
}
}
break;
case // see org.apache.openejb.batchee.BatchEEServiceManager
"org.apache.batchee.container.cdi.BatchCDIInjectionExtension":
return "true".equals(systemInstance.getProperty("tomee.batchee.cdi.use-extension", "false"));
case "org.apache.commons.jcs.jcache.cdi.MakeJCacheCDIInterceptorFriendly":
final String spi = "META-INF/services/javax.cache.spi.CachingProvider";
try {
final Enumeration<URL> appResources = Thread.currentThread().getContextClassLoader().getResources(spi);
if (appResources != null && appResources.hasMoreElements()) {
final Collection<URL> containerResources = Collections.list(containerLoader.getResources(spi));
do {
if (!containerResources.contains(appResources.nextElement())) {
log.info("Skipping JCS CDI integration cause another provide was found in the application");
return true;
}
} while (appResources.hasMoreElements());
}
} catch (final Exception e) {
// no-op
}
break;
default:
}
return false;
}
use of org.apache.openejb.loader.SystemInstance in project tomee by apache.
the class MainImpl method processSystemProperties.
private String[] processSystemProperties(String[] args) {
final ArrayList<String> argsList = new ArrayList<>();
// be changed.
for (final String arg : args) {
if (arg.contains("-Dopenejb.base")) {
final String prop = arg.substring(arg.indexOf("-D") + 2, arg.indexOf('='));
final String val = arg.substring(arg.indexOf('=') + 1);
JavaSecurityManagers.setSystemProperty(prop, val);
}
}
// get SystemInstance (the only static class in the system)
// so we'll set up all the props in it
SystemInstance systemInstance = null;
try {
SystemInstance.init(new Properties());
OptionsLog.install();
systemInstance = SystemInstance.get();
} catch (final Exception e) {
e.printStackTrace();
System.exit(2);
}
// Now read in and apply the properties specified on the command line
for (final String arg : args) {
final int idx = arg.indexOf("-D");
final int eq = arg.indexOf('=');
if (idx >= 0 && eq > idx) {
final String prop = arg.substring(idx + 2, eq);
final String val = arg.substring(eq + 1);
JavaSecurityManagers.setSystemProperty(prop, val);
systemInstance.setProperty(prop, val);
} else {
argsList.add(arg);
}
}
args = (String[]) argsList.toArray(new String[argsList.size()]);
return args;
}
Aggregations