use of org.apache.openejb.config.event.BeforeDeploymentEvent in project tomee by apache.
the class DeploymentLoader method load.
/**
* @param jarFile the app file (war, jar, ear)
* @param config potentially some more config, mainly used when linking to another system like tomcat to enrich the conf we can guess
* @return the loaded module
*/
public AppModule load(final File jarFile, final ExternalConfiguration config) throws OpenEJBException {
// verify we have a valid file
final String jarPath;
try {
jarPath = jarFile.getCanonicalPath();
} catch (final IOException e) {
throw new OpenEJBException("Invalid application file path " + jarFile, e);
}
final URL baseUrl = getFileUrl(jarFile);
// create a class loader to use for detection of module type
// do not use this class loader for any other purposes... it is
// non-temp class loader and usage will mess up JPA
// = ClassLoaderUtil.createClassLoader(jarPath, new URL[]{baseUrl}, OpenEJB.class.getClassLoader());
ClassLoader doNotUseClassLoader = null;
try {
// determine the module type
final Class<? extends DeploymentModule> moduleClass;
try {
doNotUseClassLoader = ClassLoaderUtil.createClassLoader(jarPath, new URL[] { baseUrl }, getOpenEJBClassLoader());
moduleClass = discoverModuleType(baseUrl, ClassLoaderUtil.createTempClassLoader(doNotUseClassLoader), true);
} catch (final Exception e) {
throw new UnknownModuleTypeException("Unable to determine module type for jar: " + baseUrl.toExternalForm(), e);
}
if (ResourcesModule.class.equals(moduleClass)) {
final AppModule appModule = new AppModule(null, jarPath);
final ResourcesModule module = new ResourcesModule();
module.getAltDDs().put(RESOURCES_XML, baseUrl);
ReadDescriptors.readResourcesXml(module);
module.initAppModule(appModule);
// here module is no more useful since everything is in the appmodule
return appModule;
}
//We always load AppModule, as it somewhat likes a wrapper module
if (AppModule.class.equals(moduleClass)) {
return createAppModule(jarFile, jarPath);
}
if (EjbModule.class.equals(moduleClass)) {
final URL[] urls = new URL[] { baseUrl };
SystemInstance.get().fireEvent(new BeforeDeploymentEvent(urls));
final ClassLoader classLoader = ClassLoaderUtil.createTempClassLoader(jarPath, urls, getOpenEJBClassLoader());
final AppModule appModule;
//final Class<? extends DeploymentModule> o = EjbModule.class;
final EjbModule ejbModule = createEjbModule(baseUrl, jarPath, classLoader);
// wrap the EJB Module with an Application Module
appModule = new AppModule(ejbModule);
addPersistenceUnits(appModule, baseUrl);
return appModule;
}
if (ClientModule.class.equals(moduleClass)) {
final String jarLocation = URLs.toFilePath(baseUrl);
final ClientModule clientModule = createClientModule(baseUrl, jarLocation, getOpenEJBClassLoader(), null);
// Wrap the resource module with an Application Module
return new AppModule(clientModule);
}
if (ConnectorModule.class.equals(moduleClass)) {
final String jarLocation = URLs.toFilePath(baseUrl);
final ConnectorModule connectorModule = createConnectorModule(jarLocation, jarLocation, getOpenEJBClassLoader(), null);
if (connectorModule != null) {
final List<ConnectorModule> connectorModules = new ArrayList<ConnectorModule>();
// let it be able to deploy the same connector several times
final String id = connectorModule.getModuleId();
if (!"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.connector." + id + ".skip-default", "false"))) {
connectorModules.add(connectorModule);
}
final String aliases = SystemInstance.get().getProperty("openejb.connector." + id + ".aliases");
if (aliases != null) {
for (final String alias : aliases.split(",")) {
final ConnectorModule aliasModule = createConnectorModule(jarLocation, jarLocation, getOpenEJBClassLoader(), alias);
connectorModules.add(aliasModule);
}
}
// Wrap the resource module with an Application Module
final AppModule appModule = new AppModule(connectorModules.toArray(new ConnectorModule[connectorModules.size()]));
return appModule;
}
}
if (WebModule.class.equals(moduleClass)) {
final File file = URLs.toFile(baseUrl);
// Standalone Web Module
final WebModule webModule = createWebModule(file.getAbsolutePath(), baseUrl, getOpenEJBClassLoader(), getContextRoot(), getModuleName(), config);
// important to use the webapp classloader here otherwise each time we'll check something using loadclass it will fail (=== empty classloader)
final AppModule appModule = new AppModule(webModule.getClassLoader(), file.getAbsolutePath(), new Application(), true);
addWebModule(webModule, appModule);
addWebModuleDescriptors(baseUrl, webModule, appModule);
appModule.setStandloneWebModule();
// force it for webapps
appModule.setDelegateFirst(true);
return appModule;
}
if (PersistenceModule.class.equals(moduleClass)) {
final String jarLocation = URLs.toFilePath(baseUrl);
final ClassLoader classLoader = ClassLoaderUtil.createTempClassLoader(jarPath, new URL[] { baseUrl }, getOpenEJBClassLoader());
// wrap the EJB Module with an Application Module
final AppModule appModule = new AppModule(classLoader, jarLocation);
// Persistence Units
addPersistenceUnits(appModule, baseUrl);
return appModule;
}
throw new UnsupportedModuleTypeException("Unsupported module type: " + moduleClass.getSimpleName());
} finally {
// We can safely destroy this class loader in either case, as it was not use by any modules
if (null != doNotUseClassLoader) {
ClassLoaderUtil.destroyClassLoader(doNotUseClassLoader);
}
}
}
use of org.apache.openejb.config.event.BeforeDeploymentEvent in project tomee by apache.
the class DeploymentLoader method createAppModule.
protected AppModule createAppModule(final File jarFile, final String jarPath) throws OpenEJBException {
File appDir = unpack(jarFile);
try {
appDir = appDir.getCanonicalFile();
} catch (final IOException e) {
throw new OpenEJBException("Invalid application directory " + appDir.getAbsolutePath());
}
final URL appUrl = getFileUrl(appDir);
final String appId = appDir.getAbsolutePath();
final ClassLoader tmpClassLoader = ClassLoaderUtil.createTempClassLoader(appId, new URL[] { appUrl }, getOpenEJBClassLoader());
final ResourceFinder finder = new ResourceFinder("", tmpClassLoader, appUrl);
final Map<String, URL> appDescriptors = getDescriptors(finder);
try {
//
// Find all the modules using either the application xml or by searching for all .jar, .war and .rar files.
//
final Map<String, URL> ejbModules = new LinkedHashMap<String, URL>();
final Map<String, URL> clientModules = new LinkedHashMap<String, URL>();
final Map<String, URL> resouceModules = new LinkedHashMap<String, URL>();
final Map<String, URL> webModules = new LinkedHashMap<String, URL>();
final Map<String, String> webContextRoots = new LinkedHashMap<String, String>();
final URL applicationXmlUrl = appDescriptors.get("application.xml");
final List<URL> extraLibs = new ArrayList<URL>();
final Application application;
if (applicationXmlUrl != null) {
application = unmarshal(applicationXmlUrl);
for (final Module module : application.getModule()) {
try {
if (module.getEjb() != null) {
final URL url = finder.find(module.getEjb().trim());
ejbModules.put(module.getEjb(), url);
} else if (module.getJava() != null) {
final URL url = finder.find(module.getJava().trim());
clientModules.put(module.getJava(), url);
extraLibs.add(url);
} else if (module.getConnector() != null) {
final URL url = finder.find(module.getConnector().trim());
resouceModules.put(module.getConnector(), url);
} else if (module.getWeb() != null) {
final URL url = finder.find(module.getWeb().getWebUri().trim());
webModules.put(module.getWeb().getWebUri(), url);
webContextRoots.put(module.getWeb().getWebUri(), module.getWeb().getContextRoot());
}
} catch (final IOException e) {
throw new OpenEJBException("Invalid path to module " + e.getMessage(), e);
}
}
} else {
application = new Application();
final HashMap<String, URL> files = new HashMap<String, URL>();
scanDir(appDir, files, "", false);
files.remove("META-INF/MANIFEST.MF");
// todo we should also filter URLs here using DeploymentsResolver.loadFromClasspath
createApplicationFromFiles(appId, tmpClassLoader, ejbModules, clientModules, resouceModules, webModules, files);
}
final ClassLoaderConfigurer configurer = QuickJarsTxtParser.parse(new File(appDir, "META-INF/" + QuickJarsTxtParser.FILE_NAME));
final Collection<URL> jarsXmlLib = new ArrayList<>();
if (configurer != null) {
for (final URL url : configurer.additionalURLs()) {
try {
detectAndAddModuleToApplication(appId, tmpClassLoader, ejbModules, clientModules, resouceModules, webModules, new ImmutablePair<>(URLs.toFile(url).getAbsolutePath(), url));
} catch (final Exception e) {
jarsXmlLib.add(url);
}
}
}
// lib/*
if (application.getLibraryDirectory() == null) {
application.setLibraryDirectory("lib/");
} else {
final String dir = application.getLibraryDirectory();
if (!dir.endsWith("/")) {
application.setLibraryDirectory(dir + "/");
}
}
try {
final Map<String, URL> libs = finder.getResourcesMap(application.getLibraryDirectory());
extraLibs.addAll(libs.values());
} catch (final IOException e) {
logger.warning("Cannot load libs from '" + application.getLibraryDirectory() + "' : " + e.getMessage(), e);
}
// APP-INF/lib/*
try {
final Map<String, URL> libs = finder.getResourcesMap("APP-INF/lib/");
extraLibs.addAll(libs.values());
} catch (final IOException e) {
logger.warning("Cannot load libs from 'APP-INF/lib/' : " + e.getMessage(), e);
}
// META-INF/lib/*
try {
final Map<String, URL> libs = finder.getResourcesMap("META-INF/lib/");
extraLibs.addAll(libs.values());
} catch (final IOException e) {
logger.warning("Cannot load libs from 'META-INF/lib/' : " + e.getMessage(), e);
}
// All jars nested in the Resource Adapter
final HashMap<String, URL> rarLibs = new HashMap<String, URL>();
for (final Map.Entry<String, URL> entry : resouceModules.entrySet()) {
try {
// unpack the resource adapter archive
File rarFile = URLs.toFile(entry.getValue());
rarFile = unpack(rarFile);
entry.setValue(rarFile.toURI().toURL());
scanDir(appDir, rarLibs, "");
} catch (final MalformedURLException e) {
throw new OpenEJBException("Malformed URL to app. " + e.getMessage(), e);
}
}
for (final Iterator<Map.Entry<String, URL>> iterator = rarLibs.entrySet().iterator(); iterator.hasNext(); ) {
// remove all non jars from the rarLibs
final Map.Entry<String, URL> fileEntry = iterator.next();
if (!fileEntry.getKey().endsWith(".jar")) {
continue;
}
iterator.remove();
}
final List<URL> classPath = new ArrayList<>();
classPath.addAll(ejbModules.values());
classPath.addAll(clientModules.values());
classPath.addAll(rarLibs.values());
classPath.addAll(extraLibs);
classPath.addAll(jarsXmlLib);
final URL[] urls = classPath.toArray(new URL[classPath.size()]);
SystemInstance.get().fireEvent(new BeforeDeploymentEvent(urls));
final ClassLoader appClassLoader = ClassLoaderUtil.createTempClassLoader(appId, urls, getOpenEJBClassLoader());
//
// Create the AppModule and all nested module objects
//
final AppModule appModule = new AppModule(appClassLoader, appId, application, false);
appModule.getAdditionalLibraries().addAll(extraLibs);
appModule.getAltDDs().putAll(appDescriptors);
appModule.getWatchedResources().add(appId);
if (applicationXmlUrl != null) {
appModule.getWatchedResources().add(URLs.toFilePath(applicationXmlUrl));
}
if (appDescriptors.containsKey(RESOURCES_XML)) {
final Map<String, Object> altDd = new HashMap<String, Object>(appDescriptors);
ReadDescriptors.readResourcesXml(new org.apache.openejb.config.Module(false) {
@Override
public Map<String, Object> getAltDDs() {
return altDd;
}
@Override
public void initResources(final Resources resources) {
appModule.getContainers().addAll(resources.getContainer());
appModule.getResources().addAll(resources.getResource());
appModule.getServices().addAll(resources.getService());
}
});
}
// EJB modules
for (final String moduleName : ejbModules.keySet()) {
try {
URL ejbUrl = ejbModules.get(moduleName);
// we should try to use a reference to the temp classloader
if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), ejbUrl)) {
try {
ejbUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), ejbUrl).toURI().toURL();
} catch (final MalformedURLException ignore) {
// no-op
}
}
final File ejbFile = URLs.toFile(ejbUrl);
final String absolutePath = ejbFile.getAbsolutePath();
final EjbModule ejbModule = createEjbModule(ejbUrl, absolutePath, appClassLoader);
appModule.getEjbModules().add(ejbModule);
} catch (final OpenEJBException e) {
logger.error("Unable to load EJBs from EAR: " + appId + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Application Client Modules
for (final String moduleName : clientModules.keySet()) {
try {
URL clientUrl = clientModules.get(moduleName);
// we should try to use a reference to the temp classloader
if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), clientUrl)) {
try {
clientUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), clientUrl).toURI().toURL();
} catch (final MalformedURLException ignore) {
// no-op
}
}
final File clientFile = URLs.toFile(clientUrl);
final String absolutePath = clientFile.getAbsolutePath();
final ClientModule clientModule = createClientModule(clientUrl, absolutePath, appClassLoader, null);
appModule.getClientModules().add(clientModule);
} catch (final Exception e) {
logger.error("Unable to load App Client from EAR: " + appId + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Resource modules
for (final String moduleName : resouceModules.keySet()) {
try {
URL rarUrl = resouceModules.get(moduleName);
// we should try to use a reference to the temp classloader
if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), rarUrl)) {
try {
rarUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), rarUrl).toURI().toURL();
} catch (final MalformedURLException ignore) {
// no-op
}
}
final ConnectorModule connectorModule = createConnectorModule(appId, URLs.toFilePath(rarUrl), appClassLoader, moduleName);
if (connectorModule != null) {
appModule.getConnectorModules().add(connectorModule);
}
} catch (final OpenEJBException e) {
logger.error("Unable to load RAR: " + appId + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Web modules
for (final String moduleName : webModules.keySet()) {
try {
final URL warUrl = webModules.get(moduleName);
addWebModule(appModule, warUrl, appClassLoader, webContextRoots.get(moduleName), null);
} catch (final OpenEJBException e) {
logger.error("Unable to load WAR: " + appId + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
addBeansXmls(appModule);
// Persistence Units
final Properties p = new Properties();
p.put(appModule.getModuleId(), appModule.getJarLocation());
final FileUtils base = new FileUtils(appModule.getModuleId(), appModule.getModuleId(), p);
final List<URL> filteredUrls = new ArrayList<>();
DeploymentsResolver.loadFromClasspath(base, filteredUrls, appModule.getClassLoader());
addPersistenceUnits(appModule, filteredUrls.toArray(new URL[filteredUrls.size()]));
final Object pXmls = appModule.getAltDDs().get("persistence.xml");
for (final WebModule webModule : appModule.getWebModules()) {
final List<URL> foundRootUrls = new ArrayList<>();
final List<URL> scannableUrls = webModule.getScannableUrls();
for (final URL url : scannableUrls) {
if (!addPersistenceUnits(appModule, url).isEmpty()) {
foundRootUrls.add(url);
}
}
if (pXmls != null && Collection.class.isInstance(pXmls)) {
final File webapp = webModule.getFile();
if (webapp == null) {
continue;
}
final String webappAbsolutePath = webapp.getAbsolutePath();
final Collection<URL> list = Collection.class.cast(pXmls);
for (final URL url : list) {
try {
final File file = URLs.toFile(url);
if (file.getAbsolutePath().startsWith(webappAbsolutePath)) {
foundRootUrls.add(url);
}
} catch (final IllegalArgumentException iae) {
// no-op
}
}
}
webModule.getAltDDs().put(EAR_WEBAPP_PERSISTENCE_XML_JARS, foundRootUrls);
}
for (final DeploymentModule module : appModule.getDeploymentModule()) {
module.setStandaloneModule(false);
}
return appModule;
} catch (final OpenEJBException e) {
logger.error("Unable to load EAR: " + jarPath, e);
throw e;
}
}
use of org.apache.openejb.config.event.BeforeDeploymentEvent in project tomee by apache.
the class DeploymentLoader method createWebModule.
public WebModule createWebModule(final String appId, final String warPath, final ClassLoader parentClassLoader, final String contextRoot, final String moduleName, final ExternalConfiguration config) throws OpenEJBException {
File warFile = new File(warPath);
if (!warFile.isDirectory()) {
warFile = unpack(warFile);
}
// read web.xml file
final Map<String, URL> descriptors;
try {
descriptors = getWebDescriptors(warFile);
} catch (final IOException e) {
throw new OpenEJBException("Unable to collect descriptors in web module: " + contextRoot, e);
}
final WebApp webApp;
final URL webXmlUrl = descriptors.get("web.xml");
if (webXmlUrl != null) {
webApp = ReadDescriptors.readWebApp(webXmlUrl);
} else {
// no web.xml webapp - possible since Servlet 3.0
webApp = new WebApp();
}
// determine war class path
final List<URL> webUrls = new ArrayList<>();
ensureContainerUrls();
webUrls.addAll(containerUrls);
final SystemInstance systemInstance = SystemInstance.get();
// add these urls first to ensure we load classes from here first
final String externalRepos = systemInstance.getProperty("tomee." + warFile.getName().replace(".war", "") + ".externalRepositories");
List<URL> externalUrls = null;
if (externalRepos != null) {
externalUrls = new ArrayList<URL>();
for (final String additional : externalRepos.split(",")) {
final String trim = additional.trim();
if (!trim.isEmpty()) {
try {
externalUrls.add(new File(trim).toURI().toURL());
} catch (final MalformedURLException e) {
logger.error(e.getMessage());
}
}
}
webUrls.addAll(externalUrls);
}
final Map<String, URL[]> urls = getWebappUrlsAndRars(warFile);
webUrls.addAll(Arrays.asList(urls.get(URLS_KEY)));
final List<URL> addedUrls = new ArrayList<URL>();
for (final URL url : urls.get(RAR_URLS_KEY)) {
// eager unpack to be able to use it in classloader
final File[] files = unpack(URLs.toFile(url)).listFiles();
if (files != null) {
for (final File f : files) {
if (f.getName().endsWith(".jar")) {
try {
addedUrls.add(f.toURI().toURL());
} catch (final MalformedURLException e) {
logger.warning("War path bad: " + f.getAbsolutePath(), e);
}
}
}
}
}
webUrls.addAll(addedUrls);
// context.xml can define some additional libraries
if (config != null) {
// we don't test all !=null inline to show that config will get extra params in the future and that it is hierarchic
if (config.getClasspath() != null && config.getClasspath().length > 0) {
final Set<URL> contextXmlUrls = new LinkedHashSet<>();
for (final String location : config.getClasspath()) {
try {
webUrls.add(new File(location).toURI().toURL());
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
webUrls.addAll(contextXmlUrls);
}
}
final ClassLoaderConfigurer configurer = QuickJarsTxtParser.parse(new File(warFile, "WEB-INF/" + QuickJarsTxtParser.FILE_NAME));
if (configurer != null) {
ClassLoaderConfigurer.Helper.configure(webUrls, configurer);
}
final URL[] webUrlsArray = webUrls.toArray(new URL[webUrls.size()]);
// in TomEE this is done in init hook since we don't manage tomee webapp classloader
// so here is not the best idea for tomee
// if we want to manage it in a generic way
// simply add a boolean shared between tomcat and openejb world
// to know if we should fire it or not
systemInstance.fireEvent(new BeforeDeploymentEvent(webUrlsArray, parentClassLoader));
final ClassLoader warClassLoader = ClassLoaderUtil.createTempClassLoader(appId, webUrlsArray, parentClassLoader);
// create web module
final List<URL> scannableUrls = filterWebappUrls(webUrlsArray, config == null ? null : config.customerFilter, descriptors.get(NewLoaderLogic.EXCLUSION_FILE));
// executable war will add war in scannable urls, we don't want it since it will surely contain tomee, cxf, ...
if (Boolean.parseBoolean(systemInstance.getProperty("openejb.core.skip-war-in-loader", "true"))) {
File archive = warFile;
if (!archive.getName().endsWith(".war")) {
archive = new File(warFile.getParentFile(), warFile.getName() + ".war");
final String unpackDir = systemInstance.getProperty("tomee.unpack.dir");
if (unpackDir != null && !archive.isFile()) {
try {
archive = new File(systemInstance.getBase().getDirectory(unpackDir, false), warFile.getName());
} catch (final IOException e) {
// no-op
}
}
}
if (archive.isFile()) {
try {
scannableUrls.remove(archive.toURI().toURL());
} catch (final MalformedURLException e) {
// no-op
}
}
}
if (externalUrls != null) {
for (final URL url : externalUrls) {
if (scannableUrls.contains(url)) {
scannableUrls.remove(url);
scannableUrls.add(0, url);
}
}
}
final WebModule webModule = new WebModule(webApp, contextRoot, warClassLoader, warFile.getAbsolutePath(), moduleName);
webModule.setUrls(webUrls);
webModule.setAddedUrls(addedUrls);
webModule.setRarUrls(Arrays.asList(urls.get(RAR_URLS_KEY)));
webModule.setScannableUrls(scannableUrls);
webModule.getAltDDs().putAll(descriptors);
webModule.getWatchedResources().add(warPath);
webModule.getWatchedResources().add(warFile.getAbsolutePath());
if (webXmlUrl != null && "file".equals(webXmlUrl.getProtocol())) {
webModule.getWatchedResources().add(URLs.toFilePath(webXmlUrl));
}
//If webModule object is loaded by ejbModule or persitenceModule, no need to load tag libraries, web service and JSF related staffs.
addTagLibraries(webModule);
// load webservices descriptor
addWebservices(webModule);
// load faces configuration files
addFacesConfigs(webModule);
addBeansXmls(webModule);
return webModule;
}
Aggregations