File appDir = unpack(jarFile);
URL appUrl = getFileUrl(appDir);
ClassLoader tmpClassLoader = new TemporaryClassLoader(new URL[]{appUrl}, OpenEJB.class.getClassLoader());
ResourceFinder finder = new ResourceFinder("", tmpClassLoader, appUrl);
Map<String, URL> appDescriptors = null;
try {
appDescriptors = finder.getResourcesMap("META-INF");
} catch (IOException e) {
throw new OpenEJBException("Unable to determine descriptors in jar: " + appUrl.toExternalForm(), e);
}
try {
//
// Find all the modules using either the application xml or by searching for all .jar, .war and .rar files.
//
Map<String, URL> ejbModules = new HashMap<String, URL>();
Map<String, URL> clientModules = new HashMap<String, URL>();
Map<String, URL> resouceModules = new HashMap<String, URL>();
Map<String, URL> webModules = new HashMap<String, URL>();
Map<String, String> webContextRoots = new HashMap<String, String>();
URL applicationXmlUrl = appDescriptors.get("application.xml");
Application application;
if (applicationXmlUrl != null) {
application = unmarshal(Application.class, "application.xml", applicationXmlUrl);
for (Module module : application.getModule()) {
try {
if (module.getEjb() != null) {
URL url = finder.find(module.getEjb().trim());
ejbModules.put(module.getEjb(), url);
} else if (module.getJava() != null) {
URL url = finder.find(module.getJava().trim());
clientModules.put(module.getConnector(), url);
} else if (module.getConnector() != null) {
URL url = finder.find(module.getConnector().trim());
resouceModules.put(module.getConnector(), url);
} else if (module.getWeb() != null) {
URL url = finder.find(module.getWeb().getWebUri().trim());
webModules.put(module.getWeb().getWebUri(), url);
webContextRoots.put(module.getWeb().getWebUri(), module.getWeb().getContextRoot());
}
} catch (IOException e) {
throw new OpenEJBException("Invalid path to module " + e.getMessage(), e);
}
}
} else {
application = new Application();
HashMap<String, URL> files = new HashMap<String, URL>();
scanDir(appDir, files, "");
files.remove("META-INF/MANIFEST.MF");
for (Map.Entry<String, URL> entry : files.entrySet()) {
if (entry.getKey().startsWith("lib/")) continue;
if (!entry.getKey().matches(".*\\.(jar|war|rar|ear)")) continue;
try {
ClassLoader moduleClassLoader = new TemporaryClassLoader(new URL[]{entry.getValue()}, tmpClassLoader);
Class moduleType = discoverModuleType(entry.getValue(), moduleClassLoader, true);
if (EjbModule.class.equals(moduleType)) {
ejbModules.put(entry.getKey(), entry.getValue());
} else if (ClientModule.class.equals(moduleType)) {
clientModules.put(entry.getKey(), entry.getValue());
} else if (ConnectorModule.class.equals(moduleType)) {
resouceModules.put(entry.getKey(), entry.getValue());
} else if (WebModule.class.equals(moduleType)) {
webModules.put(entry.getKey(), entry.getValue());
}
} catch (UnsupportedOperationException e) {
// Ignore it as per the javaee spec EE.8.4.2 section 1.d.iiilogger.info("Ignoring unknown module type: "+entry.getKey());
} catch (Exception e) {
throw new OpenEJBException("Unable to determine the module type of " + entry.getKey() + ": Exception: " + e.getMessage(), e);
}
}
}
//
// Create a class loader for the application
//
// lib/*
if (application.getLibraryDirectory() == null) {
application.setLibraryDirectory("lib/");
} else {
String dir = application.getLibraryDirectory();
if (!dir.endsWith("/")) application.setLibraryDirectory(dir + "/");
}
List<URL> extraLibs = new ArrayList<URL>();
try {
Map<String, URL> libs = finder.getResourcesMap(application.getLibraryDirectory());
extraLibs.addAll(libs.values());
} catch (IOException e) {
logger.warning("Cannot load libs from '" + application.getLibraryDirectory() + "' : " + e.getMessage(), e);
}
// APP-INF/lib/*
try {
Map<String, URL> libs = finder.getResourcesMap("APP-INF/lib/");
extraLibs.addAll(libs.values());
} catch (IOException e) {
logger.warning("Cannot load libs from 'APP-INF/lib/' : " + e.getMessage(), e);
}
// META-INF/lib/*
try {
Map<String, URL> libs = finder.getResourcesMap("META-INF/lib/");
extraLibs.addAll(libs.values());
} catch (IOException e) {
logger.warning("Cannot load libs from 'META-INF/lib/' : " + e.getMessage(), e);
}
// All jars nested in the Resource Adapter
HashMap<String, URL> rarLibs = new HashMap<String, URL>();
for (Map.Entry<String, URL> entry : resouceModules.entrySet()) {
try {
// unpack the resource adapter archive
File rarFile = new File(entry.getValue().getPath());
rarFile = unpack(rarFile);
entry.setValue(rarFile.toURL());
scanDir(appDir, rarLibs, "");
} catch (MalformedURLException e) {
throw new OpenEJBException("Malformed URL to app. " + e.getMessage(), e);
}
}
for (Iterator<Map.Entry<String, URL>> iterator = rarLibs.entrySet().iterator(); iterator.hasNext();) {
// remove all non jars from the rarLibs
Map.Entry<String, URL> fileEntry = iterator.next();
if (!fileEntry.getKey().endsWith(".jar")) continue;
iterator.remove();
}
List<URL> classPath = new ArrayList<URL>();
classPath.addAll(ejbModules.values());
classPath.addAll(clientModules.values());
classPath.addAll(rarLibs.values());
classPath.addAll(extraLibs);
URL[] urls = classPath.toArray(new URL[]{});
ClassLoader appClassLoader = new TemporaryClassLoader(urls, OpenEJB.class.getClassLoader());
//
// Create the AppModule and all nested module objects
//
AppModule appModule = new AppModule(appClassLoader, appDir.getAbsolutePath());
appModule.getAdditionalLibraries().addAll(extraLibs);
appModule.getAltDDs().putAll(appDescriptors);
// EJB modules
for (String moduleName : ejbModules.keySet()) {
try {
URL ejbUrl = ejbModules.get(moduleName);
File ejbFile = new File(ejbUrl.getPath());
Map<String, URL> descriptors = getDescriptors(ejbUrl);
EjbJar ejbJar = null;
if (descriptors.containsKey("ejb-jar.xml")){
ejbJar = ReadDescriptors.readEjbJar(descriptors.get("ejb-jar.xml"));
}
EjbModule ejbModule = new EjbModule(appClassLoader, moduleName, ejbFile.getAbsolutePath(), ejbJar, null);
ejbModule.getAltDDs().putAll(descriptors);
appModule.getEjbModules().add(ejbModule);
} catch (OpenEJBException e) {
logger.error("Unable to load EJBs from EAR: " + appDir.getAbsolutePath() + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Application Client Modules
for (String moduleName : clientModules.keySet()) {
try {
URL clientUrl = clientModules.get(moduleName);
File clientFile = new File(clientUrl.getPath());
ResourceFinder clientFinder = new ResourceFinder(clientUrl);
URL manifestUrl = clientFinder.find("META-INF/MANIFEST.MF");
InputStream is = manifestUrl.openStream();
Manifest manifest = new Manifest(is);
String mainClass = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
Map<String, URL> descriptors = getDescriptors(clientUrl);
ApplicationClient applicationClient = null;
if (descriptors.containsKey("application-client.xml")){
applicationClient = ReadDescriptors.readApplicationClient(descriptors.get("application-client.xml"));
}
ClientModule clientModule = new ClientModule(applicationClient, appClassLoader, clientFile.getAbsolutePath(), mainClass, moduleName);
clientModule.getAltDDs().putAll(descriptors);
appModule.getClientModules().add(clientModule);
} catch (Exception e) {
logger.error("Unable to load App Client from EAR: " + appDir.getAbsolutePath() + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Resource modules
for (String moduleName : resouceModules.keySet()) {
try {
URL rarUrl = resouceModules.get(moduleName);
File rarFile = new File(rarUrl.getPath());
Map<String, URL> descriptors = getDescriptors(rarUrl);
Connector connector = null;
if (descriptors.containsKey("ra.xml")){
connector = ReadDescriptors.readConnector(descriptors.get("ra.xml"));
}
ConnectorModule connectorModule = new ConnectorModule(connector, appClassLoader, rarFile.getAbsolutePath(), moduleName);
connectorModule.getAltDDs().putAll(descriptors);
appModule.getResourceModules().add(connectorModule);
} catch (OpenEJBException e) {
logger.error("Unable to load RAR: " + appDir.getAbsolutePath() + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Web modules
for (String moduleName : webModules.keySet()) {
try {
URL warUrl = webModules.get(moduleName);
File warFile = new File(warUrl.getPath());
// read web.xml file
Map<String, URL> descriptors = getDescriptors(warUrl);
WebApp webApp = null;
if (descriptors.containsKey("web.xml")){
webApp = ReadDescriptors.readWebApp(descriptors.get("web.xml"));
}
// determine war class path
List<URL> webClassPath = new ArrayList<URL>();
File webInfDir = new File(warFile, "WEB-INF");
try {
webClassPath.add(new File(webInfDir, "classes").toURL());
} catch (MalformedURLException e) {
logger.warning("War path bad: " + new File(webInfDir, "classes"), e);
}
File libDir = new File(webInfDir, "lib");
if (libDir.exists()) {
for (File file : libDir.listFiles()) {
if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) {
try {
webClassPath.add(file.toURL());
} catch (MalformedURLException e) {
logger.warning("War path bad: " + file, e);
}
}
}
}
// create the class loader
URL[] webUrls = webClassPath.toArray(new URL[]{});
ClassLoader warClassLoader = new TemporaryClassLoader(webUrls, appClassLoader);
// create web module
WebModule webModule = new WebModule(webApp, webContextRoots.get(moduleName), warClassLoader, warFile.getAbsolutePath(), moduleName);
webModule.getAltDDs().putAll(descriptors);
appModule.getWebModules().add(webModule);
} catch (OpenEJBException e) {
logger.error("Unable to load WAR: " + appDir.getAbsolutePath() + ", module: " + moduleName + ". Exception: " + e.getMessage(), e);
}
}
// Persistence Units
addPersistenceUnits(appModule, classLoader, urls);
return appModule;
} catch (OpenEJBException e) {
logger.error("Unable to load EAR: " + jarFile.getAbsolutePath(), e);
throw e;
}
} else if (EjbModule.class.equals(moduleClass)) {
// read the ejb-jar.xml file
Map<String, URL> descriptors = getDescriptors(baseUrl);
EjbJar ejbJar = null;
if (descriptors.containsKey("ejb-jar.xml")){
ejbJar = ReadDescriptors.readEjbJar(descriptors.get("ejb-jar.xml"));
}
// create the EJB Module
EjbModule ejbModule = new EjbModule(classLoader, jarFile.getAbsolutePath(), ejbJar, null);
ejbModule.getAltDDs().putAll(descriptors);
// wrap the EJB Module with an Application Module
AppModule appModule = new AppModule(classLoader, ejbModule.getJarLocation());
appModule.getEjbModules().add(ejbModule);
// Persistence Units
addPersistenceUnits(appModule, classLoader, baseUrl);
return appModule;
} else if (ConnectorModule.class.equals(moduleClass)) {
// unpack the rar file
File rarFile = new File(baseUrl.getPath());
rarFile = unpack(rarFile);
baseUrl = getFileUrl(rarFile);
// read the ra.xml file
Map<String, URL> descriptors = getDescriptors(baseUrl);
Connector connector = null;
if (descriptors.containsKey("ra.xml")){
connector = ReadDescriptors.readConnector(descriptors.get("ra.xml"));
}
// find the nested jar files
HashMap<String, URL> rarLibs = new HashMap<String, URL>();
scanDir(rarFile, rarLibs, "");
for (Iterator<Map.Entry<String, URL>> iterator = rarLibs.entrySet().iterator(); iterator.hasNext();) {
// remove all non jars from the rarLibs
Map.Entry<String, URL> fileEntry = iterator.next();
if (!fileEntry.getKey().endsWith(".jar")) continue;
iterator.remove();
}
// create the class loader
List<URL> classPath = new ArrayList<URL>();
classPath.addAll(rarLibs.values());
URL[] urls = classPath.toArray(new URL[]{});
ClassLoader appClassLoader = new TemporaryClassLoader(urls, OpenEJB.class.getClassLoader());
// create the Resource Module
ConnectorModule connectorModule = new ConnectorModule(connector, appClassLoader, jarFile.getAbsolutePath(), null);
connectorModule.getAltDDs().putAll(descriptors);
// Wrap the resource module with an Application Module
AppModule appModule = new AppModule(classLoader, connectorModule.getJarLocation());
appModule.getResourceModules().add(connectorModule);
// Persistence Units
addPersistenceUnits(appModule, classLoader, baseUrl);
return appModule;
} else if (WebModule.class.equals(moduleClass)) {
// unpack the rar file
File warFile = new File(baseUrl.getPath());
warFile = unpack(warFile);
baseUrl = getFileUrl(warFile);
// read the web.xml file
Map<String, URL> descriptors = getDescriptors(baseUrl);
WebApp webApp = null;
if (descriptors.containsKey("web.xml")){
webApp = ReadDescriptors.readWebApp(descriptors.get("web.xml"));
}
// determine war class path
List<URL> classPath = new ArrayList<URL>();
File webInfDir = new File(warFile, "WEB-INF");
try {
classPath.add(new File(webInfDir, "classes").toURL());
} catch (MalformedURLException e) {
logger.warning("War path bad: " + new File(webInfDir, "classes"), e);
}
File libDir = new File(webInfDir, "lib");
if (libDir.exists()) {
for (File file : libDir.listFiles()) {
if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) {
try {
classPath.add(file.toURL());
} catch (MalformedURLException e) {
logger.warning("War path bad: " + file, e);
}
}
}
}
// create the class loader
URL[] urls = classPath.toArray(new URL[]{});
ClassLoader appClassLoader = new TemporaryClassLoader(urls, OpenEJB.class.getClassLoader());
// create the Resource Module
WebModule webModule = new WebModule(webApp, null, appClassLoader, jarFile.getAbsolutePath(), null);
webModule.getAltDDs().putAll(descriptors);