Get the catalog build info from the jar bytes.
Performs sanity checks on the build info and version strings.

@param jarfile in-memory catalog jar file
@return build info lines
@throws IOException If the catalog or the version string cannot be loaded.
330445
public static String[] getBuildInfoFromJar(InMemoryJarfile jarfile)
            throws IOException
    {
        // Read the raw build info bytes.
        byte[] buildInfoBytes = jarfile.get(CATALOG_BUILDINFO_FILENAME);
        if (buildInfoBytes == null) {
            throw new IOException("Catalog build information not found - please build your application using the current version of VoltDB.");
        }

        // Convert the bytes to a string and split by lines.
        String buildInfo;
        buildInfo = new String(buildInfoBytes, Constants.UTF8ENCODING);
        String[] buildInfoLines = buildInfo.split("\n");

        // Sanity check the number of lines and the version string.
        if (buildInfoLines.length < 1) {
            throw new IOException("Catalog build info has no version string.");
        }
        String versionFromCatalog = buildInfoLines[0].trim();
        if (!CatalogUtil.isCatalogVersionValid(versionFromCatalog)) {
            throw new IOException(String.format(
                    "Catalog build info version (%s) is bad.", versionFromCatalog));
        }

        // Trim leading/trailing whitespace.
        for (int i = 0; i < buildInfoLines.length; ++i) {
            buildInfoLines[i] = buildInfoLines[i].trim();
        }

        return buildInfoLines;
    }
768728
public static JarFile getJarFile(URL url) {
		try {
			JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
			return urlConnection.getJarFile();
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
	}
988453
String getBuildVersion() {
        if (this.buildVersion == null) {
            Properties prop = new Properties();
            try {
                // try system
                URL u = ClassLoader.getSystemResource(SQLG_APPLICATION_PROPERTIES);
                if (u == null) {
                    // try own class loader
                    u = getClass().getClassLoader().getResource(SQLG_APPLICATION_PROPERTIES);
                }
                if (u != null) {
                    try (InputStream is = u.openStream()) {
                        prop.load(is);
                    }
                    this.buildVersion = prop.getProperty(APPLICATION_VERSION);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return this.buildVersion;
    }
445265
public static String findSingleMainClass(JarFile jarFile, String classesLocation)
            throws IOException {
        MainClassesCallback callback = new MainClassesCallback();
        MainClassFinder.doWithMainClasses(jarFile, classesLocation, callback);
        return callback.getMainClass();
    }
229081
public List<ClasspathResourceVersion> getResourceVersions() throws URISyntaxException, IOException {
        if (!lazyLoadDone) {
            if (isClassFolder()) {
                logger.debug("\nScanning class folder: " + getUrl());

                URI uri = new URI(getUrl());
                Path start = Paths.get(uri);

                scanClasspathEntry(start);

            } else if (isJar()) {
                logger.debug("\nScanning jar: " + getUrl());

                URI uri = new URI("jar:" + getUrl());

                try (FileSystem jarFS = FileSystems.newFileSystem(uri, new HashMap<String, String>())) {
                    Path zipInJarPath = jarFS.getPath("/");

                    scanClasspathEntry(zipInJarPath);

                } catch (Exception exc) {
                    logger.debug("Could not scan jar: " + getUrl() + " - reason:" + exc.getMessage());
                }
            }
            lazyLoadDone = true;
        }

        return resourceVersions;
    }
574721
public synchronized JarFile getNestedJarFile(JarEntryData sourceEntry)
            throws IOException {
        try {
            if (sourceEntry.nestedJar == null) {
                sourceEntry.nestedJar = createJarFileFromEntry(sourceEntry);
            }
            return sourceEntry.nestedJar;
        } catch (IOException ex) {
            throw new IOException(
                    "Unable to open nested jar file '" + sourceEntry.getName() + "'", ex);
        }
    }
767310
public static Map<String,String> unserializeBuildInfo(final String buildInfo) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.disable(MapperFeature.USE_GETTERS_AS_SETTERS);
        return mapper.readValue(buildInfo,   new TypeReference<Map<String, Object>>(){});
    }
128125
public static Manifest readManifestFromExternalJar(File jarFile) {
        if (!jarFile.getName().endsWith(".jar")) {
            throw new IllegalArgumentException("not jar file : " + jarFile);
        }
        InputStream in = null;
        String urlStr = "jar:file:" + jarFile.getAbsolutePath() + "!/META-INF/MANIFEST.MF";
          try {
            URL inputURL = new URL(urlStr);
            JarURLConnection conn = (JarURLConnection) inputURL.openConnection();
            in = conn.getInputStream();
            return new Manifest(in);
          } catch (FileNotFoundException e) {
              return null;
          } catch (IOException e) {
              throw new RuntimeException(e);
          } finally {
              IOUtils.closeQuietly(in);
          }
    }
345496
protected boolean validateJarFile(File jarfile)
        throws IOException {

        if (triggers == null)
            return (true);
        JarFile jarFile = new JarFile(jarfile);
        for (int i = 0; i < triggers.length; i++) {
            Class clazz = null;
            try {
                if (parent != null) {
                    clazz = parent.loadClass(triggers[i]);
                } else {
                    clazz = Class.forName(triggers[i]);
                }
            } catch (Throwable t) {
                clazz = null;
            }
            if (clazz == null)
                continue;
            String name = triggers[i].replace('.', '/') + ".class";
            if (log.isDebugEnabled())
                log.debug(" Checking for " + name);
            JarEntry jarEntry = jarFile.getJarEntry(name);
            if (jarEntry != null) {
                log.info("validateJarFile(" + jarfile + 
                    ") - jar not loaded. See Servlet Spec 2.3, "
                    + "section 9.7.2. Offending class: " + name);
                jarFile.close();
                return (false);
            }
        }
        jarFile.close();
        return (true);

    }
963820
public static void writeToFile(byte[] catalogBytes, File file) throws IOException {
        JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(file));

        JarInputStream jarIn = new JarInputStream(new ByteArrayInputStream(catalogBytes));
        JarEntry catEntry = null;
        JarInputStreamReader reader = new JarInputStreamReader();
        while ((catEntry = jarIn.getNextJarEntry()) != null) {
            byte[] value = reader.readEntryFromStream(jarIn);
            String key = catEntry.getName();

            assert (value != null);
            JarEntry entry = new JarEntry(key);
            entry.setSize(value.length);
            entry.setTime(System.currentTimeMillis());
            jarOut.putNextEntry(entry);
            jarOut.write(value);
            jarOut.flush();
            jarOut.closeEntry();
        }

        jarOut.finish();
        jarIn.close();
    }
319536
public static String jarVersion(JarFile jar) throws IOException {
		String version = jar.getManifest().getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
		
		if(version == null) {
			version = String.format("%d", System.currentTimeMillis());
		}
		return version;
	}
91154
@Override
    public void writeCatalogJar(byte[] catalogBytes) throws IOException
    {
        File configInfoDir = getConfigDirectory();
        configInfoDir.mkdirs();

        InMemoryJarfile.writeToFile(catalogBytes,
                                    new VoltFile(configInfoDir.getPath(),
                                                 InMemoryJarfile.TMP_CATALOG_JAR_FILENAME));
    }
483159
public static VersionMonitor getVersion(Class clazz) throws IOException {
        Manifest manifest = new Manifest();
        manifest.read(clazz.getResourceAsStream(MANIFEST_PATH));
        return getVersion(manifest);
    }
819526
private File makeGlobalJar() throws IOException {
    final File jarFile = new File(this.fileNames.getGlobalFolderName() + this.fileNames.getJarFileSuffix());
    new JARFileMaker(jarFile).addChildren(this.fileNames.getGlobalFolder()).close();
    return jarFile;
  }
199856
private void addJarFileUrl(String jarFile)
    {
        if (jarUrls == null)
        {
            jarUrls = new HashSet<URL>();
        }
        try
        {
            jarUrls.add(new File(jarFile).toURI().toURL());
        }
        catch (MalformedURLException e)
        {
            log.error("Error while mapping jar-file url" + jarFile + "caused by:" + e.getMessage());
            throw new IllegalArgumentException("Invalid jar-file URL:" + jarFile + "Caused by: " + e);
        }
    }
931788
String build() throws IOException {

		if (built) {
			// Can call build only once per instance
			throw new IllegalStateException();
		}
		built = true;

		Map<String, String> moduleCacheInfo = null;
		if (request.getAttribute(LayerImpl.LAYERCACHEINFO_PROPNAME) != null) {
			moduleCacheInfo = new HashMap<String, String>();
			request.setAttribute(IModuleCache.MODULECACHEINFO_PROPNAME, moduleCacheInfo);
		}

		if (RequestUtil.isDependencyExpansionLogging(request)) {
			DependencyList depList = (DependencyList)request.getAttribute(LayerImpl.EXPANDEDDEPS_PROPNAME);
			if (depList != null) {
				// Output dependency expansion logging
				writer.append(dependencyExpansionLogging(depList));
			}
		}

		List<ModuleBuildFuture> futures = collectFutures(moduleList, request);
		SortedReaders sorted = new SortedReaders(futures, request);

		/*
		 * Set layer dependent features attribute.  The build readers add the layer dependent features
		 * to this collection as they are read.
		 */
		request.setAttribute(ILayer.DEPENDENT_FEATURES, dependentFeatures);

		writer.append(notifyLayerListeners(EventType.BEGIN_LAYER, request, null));
		addTransportContribution(LayerContributionType.BEGIN_RESPONSE, null);

		// Add script files to the layer first.  Scripts have no transport contribution
		for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getScripts().entrySet()) {
			processReader(entry.getKey(), entry.getValue());
		}
		if (sorted.getCacheEntries().size() > 0 || sorted.getModules().size() > 0) {
			writer.append(notifyLayerListeners(EventType.BEGIN_AMD, request, null));

			// Now add the loader cache entries.
			if (sorted.getCacheEntries().size() > 0) {
				addTransportContribution(LayerContributionType.BEGIN_LAYER_MODULES, moduleList.getRequiredModules());
				int i = 0;
				for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getCacheEntries().entrySet()) {
					writer.append(notifyLayerListeners(EventType.BEGIN_MODULE, request, entry.getKey()));
					ModuleInfo info = new ModuleInfo(entry.getKey().getModuleId(), entry.getValue().isScript());
					LayerContributionType type = (i++ == 0) ? LayerContributionType.BEFORE_FIRST_LAYER_MODULE : LayerContributionType.BEFORE_SUBSEQUENT_LAYER_MODULE;
					addTransportContribution(type, info);
					processReader(entry.getKey(), entry.getValue());
					addTransportContribution(LayerContributionType.AFTER_LAYER_MODULE, info);
				}
				addTransportContribution(LayerContributionType.END_LAYER_MODULES, moduleList.getRequiredModules());
			}

			// Now add the loader requested modules
			if (sorted.getModules().size() > 0) {
				Set<String> mids = new LinkedHashSet<String>();
				for (IModule module : sorted.getModules().keySet()) {
					mids.add(module.getModuleId());
				}
				addTransportContribution(LayerContributionType.BEGIN_MODULES, mids);
				int i = 0;
				for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getModules().entrySet()) {
					writer.append(notifyLayerListeners(EventType.BEGIN_MODULE, request, entry.getKey()));
					ModuleInfo info = new ModuleInfo(entry.getKey().getModuleId(), entry.getValue().isScript());
					LayerContributionType type = (i++ == 0) ? LayerContributionType.BEFORE_FIRST_MODULE : LayerContributionType.BEFORE_SUBSEQUENT_MODULE;
					addTransportContribution(type, info);
					processReader(entry.getKey(), entry.getValue());
					addTransportContribution(LayerContributionType.AFTER_MODULE, info);
				}
				addTransportContribution(LayerContributionType.END_MODULES, mids);
			}
		}
 		writer.append(notifyLayerListeners(EventType.END_LAYER, request, null));
		addTransportContribution(LayerContributionType.END_RESPONSE, null);

		moduleList.getDependentFeatures().addAll(dependentFeatures);

		// Output any messages to the console if debug mode is enabled
		if (options.isDebugMode() || options.isDevelopmentMode()) {
			for (String errorMsg : errorMessages) {
				writer.append("\r\nconsole.error(\"" + errorMsg + "\");"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			for (String msg : nonErrorMessages) {
				writer.append("\r\nconsole.warn(\"" + msg + "\");"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
		// Help out the GC
		sorted.clear();
		futures.clear();
		layerListenerModuleList.clear();

		if (sectionCount > 0) {
			// If any of the modules in the layer contained source map info, then
			// create a source map for the layer and include the source mapping URL
			// in the response.
			writer.append("\n").append(getSourcesMappingEpilogue()); //$NON-NLS-1$
			finalizeSourceMap();
		}

		return writer.toString();
	}
1293938
private final void readDirectories(final URL jarFile) {
		JarInputStream jarIn = null;

		try {
			if (!jarFile.getPath().endsWith(".jar")) {
				return;
			}
			if (CClassLoader.sl(CClassLoader.DEBUG)) {
				CClassLoader.log("opening jar : " + jarFile.toExternalForm(),
						CClassLoader.DEBUG);
			}
			jarIn = new JarInputStream(jarFile.openStream());
			JarEntry jarEntry = null;

			while ((jarEntry = jarIn.getNextJarEntry()) != null) {
				if (jarEntry.isDirectory()) {
					continue;
				}

				final URL url = new URL("yahpjarloader://"
						+ CBASE64Codec.encode(
								jarFile.toExternalForm().getBytes("utf-8"))
								.replaceAll("\n", "") + "/"
						+ jarEntry.getName());

				if (CClassLoader.sl(CClassLoader.DEBUG)) {
					CClassLoader.log("found entry : " + url.toString(),
							CClassLoader.DEBUG);
				}

				if (jarEntry.getName().endsWith(".class")) {
					if (!this.classesMap.containsKey(jarEntry.getName())) {
						if (!this.booResourceOnly) {
							this.classesMap.put(jarEntry.getName(), url);
						}
					}

					if (this.resourcesMap.containsKey(jarEntry.getName())) {
						final Object to = this.resourcesMap.get(jarEntry
								.getName());
						if (to instanceof URL) {
							final URL uo = (URL) to;
							final List l = new ArrayList();
							l.add(uo);
							l.add(url);
							this.resourcesMap.put(jarEntry.getName(), l);
						} else if (to instanceof List) {
							final List uo = (List) to;
							uo.add(url);
							this.resourcesMap.put(jarEntry.getName(), uo);
						}
					} else {
						this.resourcesMap.put(jarEntry.getName(), url);
					}
				} else if (jarEntry.getName().startsWith("native/")) {
					String system = jarEntry.getName().substring(7);
					system = system.substring(0, system.indexOf('/'));
					if (!this.dllMap.containsKey(system)) {
						this.dllMap.put(system, url);
					}
					if (this.resourcesMap.containsKey(jarEntry.getName())) {
						final Object to = this.resourcesMap.get(jarEntry
								.getName());
						if (to instanceof URL) {
							final URL uo = (URL) to;
							final List l = new ArrayList();
							l.add(uo);
							l.add(url);
							this.resourcesMap.put(jarEntry.getName(), l);
						} else if (to instanceof List) {
							final List uo = (List) to;
							uo.add(url);
							this.resourcesMap.put(jarEntry.getName(), uo);
						}
					} else {
						this.resourcesMap.put(jarEntry.getName(), url);
					}
				} else {
					if (this.resourcesMap.containsKey(jarEntry.getName())) {
						final Object to = this.resourcesMap.get(jarEntry
								.getName());
						if (to instanceof URL) {
							final URL uo = (URL) to;
							final List l = new ArrayList();
							l.add(uo);
							l.add(url);
							this.resourcesMap.put(jarEntry.getName(), l);
						} else if (to instanceof List) {
							final List uo = (List) to;
							uo.add(url);
							this.resourcesMap.put(jarEntry.getName(), uo);
						}
					} else {
						this.resourcesMap.put(jarEntry.getName(), url);
					}
				}
			}

			if (CClassLoader.sl(CClassLoader.DEBUG)) {
				CClassLoader.log("opening jar : "
						+ jarFile.getFile().toString() + " done.",
						CClassLoader.DEBUG);
			}
		} catch (final MalformedURLException mue) {
			mue.printStackTrace();

			if (CClassLoader.sl(CClassLoader.FATAL)) {
				CClassLoader.log(mue.getMessage(), CClassLoader.FATAL);
			}
		} catch (final IOException ioe) {
			ioe.printStackTrace();

			if (CClassLoader.sl(CClassLoader.FATAL)) {
				CClassLoader.log(ioe.getMessage(), CClassLoader.FATAL);
			}
		} catch (final Exception e) {
			e.printStackTrace();

			if (CClassLoader.sl(CClassLoader.FATAL)) {
				CClassLoader.log(e.getMessage(), CClassLoader.FATAL);
			}
		} finally {
			try {
				jarIn.close();
				jarIn = null;
			} catch (final Exception e) {
			}
		}
	}