List of usage examples for java.util.jar JarFile close
public void close() throws IOException
From source file:org.openmrs.module.web.WebModuleUtil.java
/** * Performs the webapp specific startup needs for modules Normal startup is done in * {@link ModuleFactory#startModule(Module)} If delayContextRefresh is true, the spring context * is not rerun. This will save a lot of time, but it also means that the calling method is * responsible for restarting the context if necessary (the calling method will also have to * call {@link #loadServlets(Module, ServletContext)} and * {@link #loadFilters(Module, ServletContext)}).<br> * <br>//from ww w . j av a 2 s. co m * If delayContextRefresh is true and this module should have caused a context refresh, a true * value is returned. Otherwise, false is returned * * @param mod Module to start * @param servletContext the current ServletContext * @param delayContextRefresh true/false whether or not to do the context refresh * @return boolean whether or not the spring context need to be refreshed */ public static boolean startModule(Module mod, ServletContext servletContext, boolean delayContextRefresh) { if (log.isDebugEnabled()) { log.debug("trying to start module " + mod); } // only try and start this module if the api started it without a // problem. if (ModuleFactory.isModuleStarted(mod) && !mod.hasStartupError()) { String realPath = getRealPath(servletContext); if (realPath == null) { realPath = System.getProperty("user.dir"); } File webInf = new File(realPath + "/WEB-INF".replace("/", File.separator)); if (!webInf.exists()) { webInf.mkdir(); } copyModuleMessagesIntoWebapp(mod, realPath); log.debug("Done copying messages"); // flag to tell whether we added any xml/dwr/etc changes that necessitate a refresh // of the web application context boolean moduleNeedsContextRefresh = false; // copy the html files into the webapp (from /web/module/ in the module) // also looks for a spring context file. If found, schedules spring to be restarted JarFile jarFile = null; OutputStream outStream = null; InputStream inStream = null; try { File modFile = mod.getFile(); jarFile = new JarFile(modFile); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); log.debug("Entry name: " + name); if (name.startsWith("web/module/")) { // trim out the starting path of "web/module/" String filepath = name.substring(11); StringBuffer absPath = new StringBuffer(realPath + "/WEB-INF"); // If this is within the tag file directory, copy it into /WEB-INF/tags/module/moduleId/... if (filepath.startsWith("tags/")) { filepath = filepath.substring(5); absPath.append("/tags/module/"); } // Otherwise, copy it into /WEB-INF/view/module/moduleId/... else { absPath.append("/view/module/"); } // if a module id has a . in it, we should treat that as a /, i.e. files in the module // ui.springmvc should go in folder names like .../ui/springmvc/... absPath.append(mod.getModuleIdAsPath() + "/" + filepath); if (log.isDebugEnabled()) { log.debug("Moving file from: " + name + " to " + absPath); } // get the output file File outFile = new File(absPath.toString().replace("/", File.separator)); if (entry.isDirectory()) { if (!outFile.exists()) { outFile.mkdirs(); } } else { // make the parent directories in case it doesn't exist File parentDir = outFile.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } //if (outFile.getName().endsWith(".jsp") == false) // outFile = new File(absPath.replace("/", File.separator) + MODULE_NON_JSP_EXTENSION); // copy the contents over to the webapp for non directories outStream = new FileOutputStream(outFile, false); inStream = jarFile.getInputStream(entry); OpenmrsUtil.copyFile(inStream, outStream); } } else if (name.equals("moduleApplicationContext.xml") || name.equals("webModuleApplicationContext.xml")) { moduleNeedsContextRefresh = true; } else if (name.equals(mod.getModuleId() + "Context.xml")) { String msg = "DEPRECATED: '" + name + "' should be named 'moduleApplicationContext.xml' now. Please update/upgrade. "; throw new ModuleException(msg, mod.getModuleId()); } } } catch (IOException io) { log.warn("Unable to copy files from module " + mod.getModuleId() + " to the web layer", io); } finally { if (jarFile != null) { try { jarFile.close(); } catch (IOException io) { log.warn("Couldn't close jar file: " + jarFile.getName(), io); } } if (inStream != null) { try { inStream.close(); } catch (IOException io) { log.warn("Couldn't close InputStream: " + io); } } if (outStream != null) { try { outStream.close(); } catch (IOException io) { log.warn("Couldn't close OutputStream: " + io); } } } // find and add the dwr code to the dwr-modules.xml file (if defined) InputStream inputStream = null; try { Document config = mod.getConfig(); Element root = config.getDocumentElement(); if (root.getElementsByTagName("dwr").getLength() > 0) { // get the dwr-module.xml file that we're appending our code to File f = new File(realPath + "/WEB-INF/dwr-modules.xml".replace("/", File.separator)); // testing if file exists if (!f.exists()) { // if it does not -> needs to be created createDwrModulesXml(realPath); } inputStream = new FileInputStream(f); Document dwrmodulexml = getDWRModuleXML(inputStream, realPath); Element outputRoot = dwrmodulexml.getDocumentElement(); // loop over all of the children of the "dwr" tag Node node = root.getElementsByTagName("dwr").item(0); Node current = node.getFirstChild(); while (current != null) { if ("allow".equals(current.getNodeName()) || "signatures".equals(current.getNodeName()) || "init".equals(current.getNodeName())) { ((Element) current).setAttribute("moduleId", mod.getModuleId()); outputRoot.appendChild(dwrmodulexml.importNode(current, true)); } current = current.getNextSibling(); } moduleNeedsContextRefresh = true; // save the dwr-modules.xml file. OpenmrsUtil.saveDocument(dwrmodulexml, f); } } catch (FileNotFoundException e) { throw new ModuleException(realPath + "/WEB-INF/dwr-modules.xml file doesn't exist.", e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException io) { log.error("Error while closing input stream", io); } } } // mark to delete the entire module web directory on exit // this will usually only be used when an improper shutdown has occurred. String folderPath = realPath + "/WEB-INF/view/module/" + mod.getModuleIdAsPath(); File outFile = new File(folderPath.replace("/", File.separator)); outFile.deleteOnExit(); // additional checks on module needing a context refresh if (moduleNeedsContextRefresh == false && mod.getAdvicePoints() != null && mod.getAdvicePoints().size() > 0) { // AOP advice points are only loaded during the context refresh now. // if the context hasn't been marked to be refreshed yet, mark it // now if this module defines some advice moduleNeedsContextRefresh = true; } // refresh the spring web context to get the just-created xml // files into it (if we copied an xml file) if (moduleNeedsContextRefresh && delayContextRefresh == false) { if (log.isDebugEnabled()) { log.debug("Refreshing context for module" + mod); } try { refreshWAC(servletContext, false, mod); log.debug("Done Refreshing WAC"); } catch (Exception e) { String msg = "Unable to refresh the WebApplicationContext"; mod.setStartupErrorMessage(msg, e); if (log.isWarnEnabled()) { log.warn(msg + " for module: " + mod.getModuleId(), e); } try { stopModule(mod, servletContext, true); ModuleFactory.stopModule(mod, true, true); //remove jar from classloader play } catch (Exception e2) { // exception expected with most modules here if (log.isWarnEnabled()) { log.warn("Error while stopping a module that had an error on refreshWAC", e2); } } // try starting the application context again refreshWAC(servletContext, false, mod); notifySuperUsersAboutModuleFailure(mod); } } if (!delayContextRefresh && ModuleFactory.isModuleStarted(mod)) { // only loading the servlets/filters if spring is refreshed because one // might depend on files being available in spring // if the caller wanted to delay the refresh then they are responsible for // calling these two methods on the module // find and cache the module's servlets //(only if the module started successfully previously) log.debug("Loading servlets and filters for module: " + mod); loadServlets(mod, servletContext); loadFilters(mod, servletContext); } // return true if the module needs a context refresh and we didn't do it here return (moduleNeedsContextRefresh && delayContextRefresh == true); } // we aren't processing this module, so a context refresh is not necessary return false; }
From source file:org.springframework.core.io.support.PathMatchingResourcePatternResolver.java
/** * Find all resources in jar files that match the given location pattern * via the Ant-style PathMatcher.//from w w w .j a v a 2 s . com * @param rootDirResource the root directory as Resource * @param rootDirURL the pre-resolved root directory URL * @param subPattern the sub pattern to match (below the root directory) * @return a mutable Set of matching Resource instances * @throws IOException in case of I/O errors * @since 4.3 * @see java.net.JarURLConnection * @see org.springframework.util.PathMatcher */ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, URL rootDirURL, String subPattern) throws IOException { URLConnection con = rootDirURL.openConnection(); JarFile jarFile; String jarFileUrl; String rootEntryPath; boolean closeJarFile; if (con instanceof JarURLConnection) { // Should usually be the case for traditional JAR files. JarURLConnection jarCon = (JarURLConnection) con; ResourceUtils.useCachesIfNecessary(jarCon); jarFile = jarCon.getJarFile(); jarFileUrl = jarCon.getJarFileURL().toExternalForm(); JarEntry jarEntry = jarCon.getJarEntry(); rootEntryPath = (jarEntry != null ? jarEntry.getName() : ""); closeJarFile = !jarCon.getUseCaches(); } else { // No JarURLConnection -> need to resort to URL file parsing. // We'll assume URLs of the format "jar:path!/entry", with the protocol // being arbitrary as long as following the entry format. // We'll also handle paths with and without leading "file:" prefix. String urlFile = rootDirURL.getFile(); try { int separatorIndex = urlFile.indexOf(ResourceUtils.WAR_URL_SEPARATOR); if (separatorIndex == -1) { separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR); } if (separatorIndex != -1) { jarFileUrl = urlFile.substring(0, separatorIndex); rootEntryPath = urlFile.substring(separatorIndex + 2); // both separators are 2 chars jarFile = getJarFile(jarFileUrl); } else { jarFile = new JarFile(urlFile); jarFileUrl = urlFile; rootEntryPath = ""; } closeJarFile = true; } catch (ZipException ex) { if (logger.isDebugEnabled()) { logger.debug("Skipping invalid jar classpath entry [" + urlFile + "]"); } return Collections.emptySet(); } } try { if (logger.isDebugEnabled()) { logger.debug("Looking for matching resources in jar file [" + jarFileUrl + "]"); } if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) { // Root entry path must end with slash to allow for proper matching. // The Sun JRE does not return a slash here, but BEA JRockit does. rootEntryPath = rootEntryPath + "/"; } Set<Resource> result = new LinkedHashSet<>(8); for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) { JarEntry entry = entries.nextElement(); String entryPath = entry.getName(); if (entryPath.startsWith(rootEntryPath)) { String relativePath = entryPath.substring(rootEntryPath.length()); if (getPathMatcher().match(subPattern, relativePath)) { result.add(rootDirResource.createRelative(relativePath)); } } } return result; } finally { if (closeJarFile) { jarFile.close(); } } }
From source file:org.jenkins.tools.test.PluginCompatTester.java
/** * Scans through a WAR file, accumulating plugin information * @param war WAR to scan/* w w w . j a v a2 s.c o m*/ * @param pluginGroupIds Map pluginName to groupId if set in the manifest, MUTATED IN THE EXECUTION * @return Update center data * @throws IOException */ private UpdateSite.Data scanWAR(File war, Map<String, String> pluginGroupIds) throws IOException { JSONObject top = new JSONObject(); top.put("id", DEFAULT_SOURCE_ID); JSONObject plugins = new JSONObject(); JarFile jf = new JarFile(war); if (pluginGroupIds == null) { pluginGroupIds = new HashMap<String, String>(); } try { Enumeration<JarEntry> entries = jf.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); Matcher m = Pattern.compile("WEB-INF/lib/jenkins-core-([0-9.]+(?:-[0-9.]+)?(?:-SNAPSHOT)?)[.]jar") .matcher(name); if (m.matches()) { if (top.has("core")) { throw new IOException(">1 jenkins-core.jar in " + war); } top.put("core", new JSONObject().accumulate("name", "core").accumulate("version", m.group(1)) .accumulate("url", "")); } m = Pattern.compile("WEB-INF/(?:optional-)?plugins/([^/.]+)[.][hj]pi").matcher(name); if (m.matches()) { JSONObject plugin = new JSONObject().accumulate("url", ""); InputStream is = jf.getInputStream(entry); try { JarInputStream jis = new JarInputStream(is); try { Manifest manifest = jis.getManifest(); String shortName = manifest.getMainAttributes().getValue("Short-Name"); if (shortName == null) { shortName = manifest.getMainAttributes().getValue("Extension-Name"); if (shortName == null) { shortName = m.group(1); } } plugin.put("name", shortName); pluginGroupIds.put(shortName, manifest.getMainAttributes().getValue("Group-Id")); plugin.put("version", manifest.getMainAttributes().getValue("Plugin-Version")); plugin.put("url", "jar:" + war.toURI() + "!/" + name); JSONArray dependenciesA = new JSONArray(); String dependencies = manifest.getMainAttributes().getValue("Plugin-Dependencies"); if (dependencies != null) { // e.g. matrix-auth:1.0.2;resolution:=optional,credentials:1.8.3;resolution:=optional for (String pair : dependencies.replace(";resolution:=optional", "").split(",")) { String[] nameVer = pair.split(":"); assert nameVer.length == 2; dependenciesA.add(new JSONObject().accumulate("name", nameVer[0]) .accumulate("version", nameVer[1]) ./* we do care about even optional deps here */accumulate("optional", "false")); } } plugin.accumulate("dependencies", dependenciesA); plugins.put(shortName, plugin); } finally { jis.close(); } } finally { is.close(); } } } } finally { jf.close(); } top.put("plugins", plugins); if (!top.has("core")) { throw new IOException("no jenkins-core.jar in " + war); } System.out.println("Scanned contents of " + war + ": " + top); return newUpdateSiteData(new UpdateSite(DEFAULT_SOURCE_ID, null), top); }
From source file:org.lockss.plugin.PluginManager.java
/** * Given a file representing a JAR, retrieve a list of available * plugin classes to load./* w w w .j ava 2 s. c om*/ */ private List<String> getJarPluginClasses(File blessedJar) throws IOException { JarFile jar = new JarFile(blessedJar); Manifest manifest = jar.getManifest(); Map entries = manifest.getEntries(); List<String> plugins = new ArrayList<String>(); for (Iterator manIter = entries.keySet().iterator(); manIter.hasNext();) { String key = (String) manIter.next(); Attributes attrs = manifest.getAttributes(key); if (attrs.containsKey(LOADABLE_PLUGIN_ATTR)) { String s = StringUtil.replaceString(key, "/", "."); String pluginName = null; if (StringUtil.endsWithIgnoreCase(key, ".class")) { pluginName = StringUtil.replaceString(s, ".class", ""); log.debug2("Adding '" + pluginName + "' to plugin load list."); plugins.add(pluginName); } else if (StringUtil.endsWithIgnoreCase(key, ".xml")) { pluginName = StringUtil.replaceString(s, ".xml", ""); log.debug2("Adding '" + pluginName + "' to plugin load list."); plugins.add(pluginName); } } } jar.close(); return plugins; }
From source file:org.wso2.carbon.tomcat.internal.CarbonTomcat.java
/** * web-app addition/*w w w . j a v a 2 s . co m*/ * * @param host virtual host for the webapp * @param contextPath unique web-app context * @param webappFilePath File location of the web-app * @param lifecycleListener tomcat life-cycle listener * @return {@link Context} object of the added web-app */ @Override public Context addWebApp(Host host, String contextPath, String webappFilePath, LifecycleListener lifecycleListener) throws CarbonTomcatException { JarFile webappJarFile = null; JarEntry contextXmlFileEntry; Context ctx = null; boolean removeContext = false; try { Container child = host.findChild(contextPath); if (child != null) { if (ctx != null && host != null) { ctx.setRealm(null); try { ctx.stop(); } catch (LifecycleException x) { log.error("Cannot stop context ", x); } host.removeChild(ctx); } } ctx = new StandardContext(); ctx.setName(contextPath); ctx.setPath(contextPath); ctx.setDocBase(webappFilePath); ctx.setRealm(host.getRealm()); //We dont need to init the DefaultWebXML since we maintain a web.xml file for a carbon server. // hence removing ctx.addLifecycleListener(new Tomcat.DefaultWebXmlListener()); code if (lifecycleListener != null) { ctx.addLifecycleListener(lifecycleListener); } SCIRegistrarContextConfig sciRegistrarContextConfig = new SCIRegistrarContextConfig(); ctx.addLifecycleListener(sciRegistrarContextConfig); // Set global webXml to this context if (new File(globalWebXml).exists()) { sciRegistrarContextConfig.setDefaultWebXml(globalWebXml); } else { sciRegistrarContextConfig.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML"); } if (new File(globalContextXml).exists()) { sciRegistrarContextConfig.setDefaultContextXml(globalContextXml); } File f = new File(webappFilePath); //During dir based webapp deployment if (f.isDirectory()) { File cf = new File(webappFilePath + File.separator + Constants.ApplicationContextXml); if (cf.exists()) { ctx.setConfigFile(cf.toURI().toURL()); } } else { // Check for embedded contextXml file in this webapp webappJarFile = new JarFile(webappFilePath); contextXmlFileEntry = webappJarFile.getJarEntry(Constants.ApplicationContextXml); if (contextXmlFileEntry != null) { ctx.setConfigFile(new URL("jar:file:" + URLEncoder.encode(webappFilePath, "UTF-8") + "!/" + Constants.ApplicationContextXml)); } } if (ctx instanceof StandardContext) { ((StandardContext) ctx).setClearReferencesStopTimerThreads(true); } if (host == null) { host = this.getHost(); } host.addChild(ctx); if (ctx.getState().equals(LifecycleState.STOPPED)) { ctx.setRealm(null); ctx.destroy(); throw new Exception("Webapp failed to deploy, Lifecycle state is STOPPED"); } if (log.isDebugEnabled()) { log.debug("Webapp context: " + ctx); } } catch (Exception e) { //since any exception can be thrown from Lifecycles, "Exception" is been caught. removeContext = true; throw new CarbonTomcatException("Webapp failed to deploy", e); } finally { if (removeContext && ctx != null && host != null) { ctx.setRealm(null); try { if (!ctx.getState().equals(LifecycleState.STOPPED)) { ctx.stop(); } } catch (LifecycleException e) { log.error("Cannot stop context ", e); } host.removeChild(ctx); log.error("Webapp " + ctx + " failed to deploy"); } if (webappJarFile != null) { try { webappJarFile.close(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); } } } return ctx; }
From source file:org.regenstrief.util.Util.java
private final static Class<?>[] getClasses(final Criterion nameCriterion, final Criterion classCriterion, final String ext) { final String[] _paths = getClassPath(); List<String> paths = Arrays.asList(_paths); if (ext != null) { paths = new ArrayList<String>(paths); paths.add(ext);/*from w w w . j a v a2 s.com*/ } final List<Resource> nameList = new ArrayList<Resource>(); for (final String path : paths) { //log.info(path); final File f = new File(path); if (f.isDirectory()) { final int pathLength = f.getAbsolutePath().length() + 1; for (final File child : getAllFiles(f)) { //log.info('\t' + child.getAbsolutePath().substring(pathLength)); nameList.add(new Resource(path, child.getAbsolutePath().substring(pathLength))); } } else if (path.endsWith(".jar")) { final JarFile jf; try { jf = new JarFile(f); } catch (final IOException e) { throw toRuntimeException(e); } final Enumeration<JarEntry> entries = jf.entries(); while (entries.hasMoreElements()) { nameList.add(new Resource(path, entries.nextElement().getName())); } try { jf.close(); } catch (final IOException e) { // Can't close } } } final List<Class<?>> classList = new ArrayList<Class<?>>(); final Set<String> nameSet = new HashSet<String>(); for (final Resource resource : nameList) { final String childName = resource.resourcePath; if (childName.endsWith(".class")) { final String className = childName.substring(0, childName.length() - 6).replace('/', '.') .replace('\\', '.'); if (((nameCriterion == null) || nameCriterion.isMet(className)) && !nameSet.contains(className)) { nameSet.add(className); final Class<?> c; try { c = ReflectUtil.forName(className); //} catch (final NoClassDefFoundError e) //{ // Just keep looking //} catch (final IncompatibleClassChangeError e) //{ // Just keep looking } catch (final Throwable e) { throw new RuntimeException("Error loading class " + className + " from " + childName + " in " + resource.containerPath, e); } if ((classCriterion == null) || classCriterion.isMet(c)) { addIfNotContainedOrNull(classList, c); } } } } return classList.toArray(EMPTY_ARRAY_CLASS); }
From source file:org.regenstrief.util.Util.java
/** * Writes information about a .jar/* w ww. j a v a 2 s . co m*/ * * @param path the path of the .jar * @param w the Writer * @throws Exception if an I/O problem occurs **/ public final static void jarInfo(final String path, final Writer w) throws Exception { final JarFile jar = new JarFile(new File(path)); final Enumeration<JarEntry> en = jar.entries(); final PrintWriter pw = getPrintWriter(w); while (en.hasMoreElements()) { final String name = en.nextElement().getName(); if (!name.endsWith(".class")) { continue; } try { Class<?> c = Class.forName(name.substring(0, name.length() - 6).replace('/', '.')); final Member[][] allMembers = new Member[][] { c.getFields(), c.getConstructors(), c.getMethods() }; pw.print(c); for (c = c.getSuperclass(); c != null; c = c.getSuperclass()) { pw.print(" extends "); pw.print(c.getName()); } pw.println(); pw.println('{'); for (int j = 0; j < allMembers.length; j++) { final Member[] members = allMembers[j]; for (final Member member : members) { if (!Modifier.isPublic(member.getModifiers())) { continue; } pw.print('\t'); pw.print(member); pw.println(';'); } if ((members.length > 0) && (j < allMembers.length - 1)) { pw.println(); } } pw.println('}'); } catch (final Throwable e) { pw.println(e); } pw.println(); } pw.flush(); jar.close(); }
From source file:org.openmrs.module.ModuleFileParser.java
/** * Get the module// w w w. j a v a2 s .c o m * * @return new module object */ public Module parse() throws ModuleException { Module module = null; JarFile jarfile = null; InputStream configStream = null; try { try { jarfile = new JarFile(moduleFile); } catch (IOException e) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.cannotGetJarFile"), moduleFile.getName(), e); } // look for config.xml in the root of the module ZipEntry config = jarfile.getEntry("config.xml"); if (config == null) { throw new ModuleException(Context.getMessageSourceService().getMessage("Module.error.noConfigFile"), moduleFile.getName()); } // get a config file stream try { configStream = jarfile.getInputStream(config); } catch (IOException e) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.cannotGetConfigFileStream"), moduleFile.getName(), e); } // turn the config file into an xml document Document configDoc = null; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); db.setEntityResolver(new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { // When asked to resolve external entities (such as a // DTD) we return an InputSource // with no data at the end, causing the parser to ignore // the DTD. return new InputSource(new StringReader("")); } }); configDoc = db.parse(configStream); } catch (Exception e) { log.error("Error parsing config.xml: " + configStream.toString(), e); OutputStream out = null; String output = ""; try { out = new ByteArrayOutputStream(); // Now copy bytes from the URL to the output stream byte[] buffer = new byte[4096]; int bytes_read; while ((bytes_read = configStream.read(buffer)) != -1) { out.write(buffer, 0, bytes_read); } output = out.toString(); } catch (Exception e2) { log.warn("Another error parsing config.xml", e2); } finally { try { out.close(); } catch (Exception e3) { } } log.error("config.xml content: " + output); throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.cannotParseConfigFile"), moduleFile.getName(), e); } Element rootNode = configDoc.getDocumentElement(); String configVersion = rootNode.getAttribute("configVersion").trim(); if (!validConfigVersions.contains(configVersion)) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.invalidConfigVersion", new Object[] { configVersion }, Context.getLocale()), moduleFile.getName()); } String name = getElement(rootNode, configVersion, "name").trim(); String moduleId = getElement(rootNode, configVersion, "id").trim(); String packageName = getElement(rootNode, configVersion, "package").trim(); String author = getElement(rootNode, configVersion, "author").trim(); String desc = getElement(rootNode, configVersion, "description").trim(); String version = getElement(rootNode, configVersion, "version").trim(); // do some validation if (name == null || name.length() == 0) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.nameCannotBeEmpty"), moduleFile.getName()); } if (moduleId == null || moduleId.length() == 0) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.idCannotBeEmpty"), name); } if (packageName == null || packageName.length() == 0) { throw new ModuleException( Context.getMessageSourceService().getMessage("Module.error.packageCannotBeEmpty"), name); } // create the module object module = new Module(name, moduleId, packageName, author, desc, version); // find and load the activator class module.setActivatorName(getElement(rootNode, configVersion, "activator").trim()); module.setRequireDatabaseVersion( getElement(rootNode, configVersion, "require_database_version").trim()); module.setRequireOpenmrsVersion(getElement(rootNode, configVersion, "require_version").trim()); module.setUpdateURL(getElement(rootNode, configVersion, "updateURL").trim()); module.setRequiredModulesMap(getRequiredModules(rootNode, configVersion)); module.setAwareOfModulesMap(getAwareOfModules(rootNode, configVersion)); module.setStartBeforeModulesMap(getStartBeforeModules(rootNode, configVersion)); module.setAdvicePoints(getAdvice(rootNode, configVersion, module)); module.setExtensionNames(getExtensions(rootNode, configVersion)); module.setPrivileges(getPrivileges(rootNode, configVersion)); module.setGlobalProperties(getGlobalProperties(rootNode, configVersion)); module.setMessages(getMessages(rootNode, configVersion, jarfile, moduleId, version)); module.setMappingFiles(getMappingFiles(rootNode, configVersion, jarfile)); module.setPackagesWithMappedClasses(getPackagesWithMappedClasses(rootNode, configVersion)); module.setConfig(configDoc); module.setMandatory(getMandatory(rootNode, configVersion, jarfile)); module.setFile(moduleFile); module.setConditionalResources(getConditionalResources(rootNode)); } finally { try { jarfile.close(); } catch (Exception e) { log.warn("Unable to close jarfile: " + jarfile, e); } if (configStream != null) { try { configStream.close(); } catch (Exception io) { log.error("Error while closing config stream for module: " + moduleFile.getAbsolutePath(), io); } } } return module; }
From source file:org.jahia.utils.maven.plugin.osgi.CheckDependenciesMojo.java
@Override public void execute() throws MojoExecutionException { setBuildDirectory(projectBuildDirectory); setOutputDirectory(new File(projectOutputDirectory)); if (!"jar".equals(project.getPackaging()) && !"bundle".equals(project.getPackaging()) && !"war".equals(project.getPackaging())) { getLog().info("Not a JAR/WAR/Bundle project, will do nothing."); return;// w w w . j a va2 s. c o m } loadSystemPackages(); buildExclusionPatterns(); Set<PackageInfo> explicitPackageImports = new TreeSet<PackageInfo>(); final ParsingContext projectParsingContext = new ParsingContext( MavenAetherHelperUtils.getCoords(project.getArtifact()), 0, 0, project.getArtifactId(), project.getBasedir().getPath(), project.getVersion(), null); List<PackageInfo> bundlePluginExplicitPackages = new ArrayList<PackageInfo>(); Map<String, String> originalInstructions = new LinkedHashMap<String, String>(); try { Xpp3Dom felixBundlePluginConfiguration = (Xpp3Dom) project .getPlugin("org.apache.felix:maven-bundle-plugin").getConfiguration(); if (felixBundlePluginConfiguration != null) { Xpp3Dom instructionsDom = felixBundlePluginConfiguration.getChild("instructions"); for (Xpp3Dom instructionChild : instructionsDom.getChildren()) { originalInstructions.put(instructionChild.getName(), instructionChild.getValue()); } if (felixBundlePluginConfiguration.getChild("excludeDependencies") != null) { excludeDependencies = felixBundlePluginConfiguration.getChild("excludeDependencies").getValue(); } getBundlePluginExplicitPackageImports(projectParsingContext, bundlePluginExplicitPackages, originalInstructions); } } catch (Exception e) { // no overrides getLog().info( "No maven-bundle-plugin found, will not use dependency exclude or deal with explicit Import-Package configurations. (" + e.getMessage() + ")"); } Properties properties = new Properties(); try { Builder builder = getOSGiBuilder(project, originalInstructions, properties, getClasspath(project)); resolveEmbeddedDependencies(project, builder); } catch (Exception e) { throw new MojoExecutionException("Error trying to process bundle plugin instructions", e); } List<PackageInfo> existingPackageImports = getExistingImportPackages(projectParsingContext); explicitPackageImports.addAll(existingPackageImports); parsingContextCache = new ParsingContextCache(new File(dependencyParsingCacheDirectory), null); long timer = System.currentTimeMillis(); int scanned = 0; try { scanClassesBuildDirectory(projectParsingContext); getLog().info("Scanned classes directory in " + (System.currentTimeMillis() - timer) + " ms. Found " + projectParsingContext.getLocalPackages().size() + " project packages."); scanned = scanDependencies(projectParsingContext); } catch (IOException e) { throw new MojoExecutionException("Error while scanning dependencies", e); } catch (DependencyResolutionRequiredException e) { throw new MojoExecutionException("Error while scanning project packages", e); } getLog().info("Scanned " + scanned + " project dependencies in " + (System.currentTimeMillis() - timer) + " ms. Currently we have " + projectParsingContext.getLocalPackages().size() + " project packages."); projectParsingContext.postProcess(); if (projectParsingContext.getSplitPackages().size() > 0) { if (failBuildOnSplitPackages) { StringBuilder splitPackageList = new StringBuilder(); for (PackageInfo packageInfo : projectParsingContext.getSplitPackages()) { splitPackageList.append(" "); splitPackageList.append(packageInfo.toString()); splitPackageList.append(" from locations:\n "); splitPackageList.append(StringUtils.join(packageInfo.getSourceLocations(), "\n ")); splitPackageList.append("\n"); } throw new MojoExecutionException("Detected split packages:\n" + splitPackageList.toString()); } } String extension = project.getPackaging(); if ("bundle".equals(extension)) { extension = "jar"; } String artifactFilePath = project.getBuild().getDirectory() + "/" + project.getBuild().getFinalName() + "." + extension; File artifactFile = new File(artifactFilePath); if (artifactFile == null || !artifactFile.exists()) { throw new MojoExecutionException( "No artifact generated for project, was the goal called in the proper phase (should be verify) ?"); } Set<FullyEqualPackageInfo> allPackageExports = collectAllDependenciesExports(projectParsingContext, new HashSet<String>()); Set<PackageInfo> missingPackageExports = new TreeSet<PackageInfo>(); JarFile jarFile = null; try { jarFile = new JarFile(artifactFile); Manifest manifest = jarFile.getManifest(); if (manifest.getMainAttributes() == null) { throw new MojoExecutionException( "Error reading OSGi bundle manifest data from artifact " + artifactFile); } String importPackageHeaderValue = manifest.getMainAttributes().getValue("Import-Package"); Set<String> visitedPackageImports = new TreeSet<String>(); if (importPackageHeaderValue != null) { List<ManifestValueClause> importPackageClauses = BundleUtils.getHeaderClauses("Import-Package", importPackageHeaderValue); List<ManifestValueClause> clausesToRemove = new ArrayList<ManifestValueClause>(); boolean modifiedImportPackageClauses = false; for (ManifestValueClause importPackageClause : importPackageClauses) { for (String importPackagePath : importPackageClause.getPaths()) { String clauseVersion = importPackageClause.getAttributes().get("version"); String clauseResolution = importPackageClause.getDirectives().get("resolution"); boolean optionalClause = false; if ("optional".equals(clauseResolution)) { optionalClause = true; } else if ("mandatory".equals(clauseResolution)) { // the resolution directive is explicitely specified as mandatory, we won't modify it optionalClause = false; } else { if (containsPackage(existingPackageImports, importPackagePath) || containsPackage(bundlePluginExplicitPackages, importPackagePath)) { // the package was explicitely configured either through Maven properties or through // explicit configuration in the bundle plugin, in this case we will not touch the // package's resolution directive getLog().info("Explicit package configuration found for " + importPackagePath + ", will not mark as optional."); } else { importPackageClause.getDirectives().put("resolution", "optional"); modifiedImportPackageClauses = true; } } if (visitedPackageImports.contains(importPackagePath)) { getLog().warn("Duplicate import detected on package " + importPackagePath + ", will remove duplicate. To remove this warning remove the duplicate import (possibly coming from a explicit import in the maven-bundle-plugin instructions)"); clausesToRemove.add(importPackageClause); modifiedImportPackageClauses = true; } // PackageInfo importPackageInfo = new PackageInfo(importPackagePath, clauseVersion, optionalClause, artifactFile.getPath(), projectParsingContext); // if (!optionalClause) { // if (PackageUtils.containsMatchingVersion(allPackageExports, importPackageInfo) // && !importPackageInfo.isOptional()) { // // we must now check if the import is strict and if the available export is part of // // an optional export, in which case we will have to change it to be optional // for (PackageInfo packageExport : allPackageExports) { // if (packageExport.matches(importPackageInfo)) { // if (packageExport.getOrigin() != null) { // ParsingContext parsingContext = packageExport.getOrigin(); // if (parsingContext.isOptional()) { // // JAR is optional, we should modify the import package clause to be optional too ! // getLog().warn("Mandatory package import " + importPackageInfo + " provided by optional JAR " + getTrail(packageExport) + " will be forced as optional !"); // importPackageClause.getDirectives().put("resolution", "optional"); // modifiedImportPackageClauses = true; // } // } // } // } // } // if (!PackageUtils.containsIgnoreVersion(allPackageExports, importPackageInfo) && // !PackageUtils.containsIgnoreVersion(systemPackages, importPackageInfo) && // !PackageUtils.containsIgnoreVersion(projectParsingContext.getLocalPackages(), importPackageInfo)) { // missingPackageExports.add(importPackageInfo); // } // } visitedPackageImports.add(importPackagePath); } } if (modifiedImportPackageClauses) { for (ManifestValueClause clauseToRemove : clausesToRemove) { boolean removeSuccessful = importPackageClauses.remove(clauseToRemove); if (!removeSuccessful) { getLog().warn("Removal of clause " + clauseToRemove + " was not successful, duplicates may still remain in Manifest !"); } } updateBundle(manifest, importPackageClauses, artifactFile, buildDirectory); } } } catch (IOException e) { throw new MojoExecutionException( "Error reading OSGi bundle manifest data from artifact " + artifactFile, e); } finally { if (jarFile != null) { try { jarFile.close(); } catch (IOException e) { // do nothing if close fails } } } missingPackageExports.removeAll(explicitPackageImports); if (missingPackageExports.size() > 0) { List<String> missingPackageNames = new ArrayList<String>(); for (PackageInfo missingPackageExport : missingPackageExports) { missingPackageNames.add(missingPackageExport.getName()); } getLog().info("Search for code origin of " + missingPackageExports.size() + " missing package imports, please wait..."); final Map<String, Map<String, Artifact>> packageResults = FindPackageUsesMojo.findPackageUses( missingPackageNames, project.getArtifacts(), project, outputDirectory, searchInDependencies, getLog()); if (packageResults.size() == 0) { getLog().warn( "No results found in project files, use the <searchInDependencies>true</searchInDependencies> parameter to make the plugin look in all the dependencies (which is MUCH slower !)"); } StringBuilder optionaDirectivesBuilder = new StringBuilder(); StringBuilder errorMessageBuilder = new StringBuilder(); String separator = ""; for (PackageInfo missingPackageExport : missingPackageExports) { optionaDirectivesBuilder.append(separator); errorMessageBuilder.append(missingPackageExport); List<String> artifactIDs = findPackageInMavenCentral(missingPackageExport.getName()); if (artifactIDs.size() > 0) { String artifactList = StringUtils.join(artifactIDs, ", "); errorMessageBuilder.append(" (available from Maven Central artifacts "); errorMessageBuilder.append(artifactList); errorMessageBuilder.append(",... or more at "); errorMessageBuilder.append(PackageUtils.getPackageSearchUrl(missingPackageExport.getName())); errorMessageBuilder.append(" )"); } else { errorMessageBuilder.append(" (not found at Maven Central, is it part of JDK ?)"); } missingPackageExport.setOptional(true); missingPackageExport.setVersion(null); optionaDirectivesBuilder.append(missingPackageExport); if (packageResults.containsKey(missingPackageExport.getName())) { Map<String, Artifact> sourceLocations = packageResults.get(missingPackageExport.getName()); for (Map.Entry<String, Artifact> foundClass : sourceLocations.entrySet()) { if (!foundClass.getValue().toString().equals(project.getArtifact().toString())) { errorMessageBuilder.append("\n used in class " + foundClass.getKey() + " (" + foundClass.getValue().getFile() + ")"); } else { errorMessageBuilder.append("\n used in class " + foundClass.getKey() + " (in project or embedded dependencies)"); } } } errorMessageBuilder.append("\n\n"); separator = ",\n"; } getLog().warn( "Couldn't find any exported packages in Maven project dependencies for the following imported packages:\n" + errorMessageBuilder.toString()); getLog().warn( "Use the following lines in the <Import-Package> maven-bundle-plugin configuration to ignore these packages :\n" + optionaDirectivesBuilder.toString()); getLog().warn( " or add the missing dependencies to your Maven project by finding the related missing Maven dependency"); getLog().warn(""); getLog().warn( "Bundle may not deploy successfully unless the above dependencies are either deployed, added to Maven project or marked explicitely as optional (as in the above list)"); getLog().warn( "If you prefer to keep this warning activated but not fail the build, simply add <failBuildOnMissingPackageExports>false</failBuildOnMissingPackageExports> to the check-dependencies goal of the jahia-maven-plugin"); getLog().warn(""); getLog().warn( "You could also use mvn jahia:find-package-uses -DpackageNames=COMMA_SEPARATED_PACKAGE_LIST to find where a specific package is used in the project"); getLog().warn( "or mvn jahia:find-packages -DpackageNames=COMMA_SEPARATED_PACKAGE_LIST to find the packages inside the project"); getLog().warn(""); if (failBuildOnMissingPackageExports) { throw new MojoExecutionException( "Missing package exports for imported packages (see build log for details)"); } } }