org.apache.sysml.utils.lite.BuildLite Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of systemml Show documentation
Show all versions of systemml Show documentation
Declarative Machine Learning
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sysml.utils.lite;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.math3.random.Well1024a;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.ThrowableInformation;
/**
* Builds a light-weight SystemML jar file based on loaded classes and
* additional resources. Additionally generates maven assembly dependency sets
* that are used by the lite.xml assembly. Note that the jar file automatically
* built by createLiteJar will only contain required SystemML classes, whereas
* the assembly jar file (built by lite.xml) includes all SystemML classes. All
* log4j classes are included in both the automatic jar and the assembly jar.
* All commons-math3 classes are included by default in both the automatic jar
* and the assembly jar, but this can be switched using createLiteJar to only
* include the detected required commons-math3 classes.
*
*/
public class BuildLite {
/**
* Default lite jar path and name.
*/
public static final String DEFAULT_LITE_JAR_LOCATION = "systemml-lite.jar";
/**
* File within the lite jar that can be used to identify execution from the
* lite jar.
*/
public static final String LITE_JAR_IDENTIFIER_FILE = "META-INF/systemml-lite.txt";
/**
* The lite jar path and name.
*/
private static String liteJarLocation = DEFAULT_LITE_JAR_LOCATION;
/**
* Additional resources that should be added to the lite jar file. This can
* include resources such as service files and shutdown hooks that aren't
* detected by query to the classloader.
*/
public static List additionalResources = new ArrayList<>();
static {
// avoid "No FileSystem for scheme: file" error in JMLC
additionalResources.add("META-INF/services/org.apache.hadoop.fs.FileSystem");
// shutdown hook class
additionalResources.add("org/apache/hadoop/util/ShutdownHookManager$2.class");
additionalResources.add("org/apache/hadoop/log/metrics/EventCounter.class");
additionalResources.add("org/apache/hadoop/util/GenericOptionsParser.class");
additionalResources.add("org/apache/hadoop/security/token/Token.class");
additionalResources.add("org/apache/hadoop/security/token/TokenIdentifier.class");
additionalResources.add("org/apache/hadoop/security/Groups$CachedGroups.class");
additionalResources.add("org/apache/commons/cli/OptionValidator.class");
additionalResources.add("org/apache/commons/cli/Util.class");
additionalResources.add("common-version-info.properties");
}
/**
* Map jars to the additional resources files in order to build the
* dependency sets required by lite.xml.
*/
public static SortedMap> additionalJarToFileMappingsForDependencySets = new TreeMap<>();
static {
SortedSet hadoopCommonResources = new TreeSet<>();
hadoopCommonResources.add("META-INF/services/org.apache.hadoop.fs.FileSystem");
hadoopCommonResources.add("org/apache/hadoop/util/ShutdownHookManager$2.class");
hadoopCommonResources.add("org/apache/hadoop/log/metrics/EventCounter.class");
hadoopCommonResources.add("org/apache/hadoop/util/GenericOptionsParser.class");
hadoopCommonResources.add("org/apache/hadoop/security/token/Token.class");
hadoopCommonResources.add("org/apache/hadoop/security/token/TokenIdentifier.class");
hadoopCommonResources.add("org/apache/hadoop/security/Groups$CachedGroups.class");
hadoopCommonResources.add("common-version-info.properties");
additionalJarToFileMappingsForDependencySets.put("hadoop-common", hadoopCommonResources);
SortedSet commonsCliResources = new TreeSet();
commonsCliResources.add("org/apache/commons/cli/OptionValidator.class");
commonsCliResources.add("org/apache/commons/cli/Util.class");
additionalJarToFileMappingsForDependencySets.put("commons-cli", commonsCliResources);
}
/**
* Scan project *.java files for these packages/classes that should
* definitely be included in the lite jar.
*/
public static List additionalPackages = new ArrayList<>();
static {
// math3, lang3, io, etc.
additionalPackages.add("org.apache.commons");
}
/**
* Exclude classes of the following packages from the lite jar.
*/
public static List packagesToExclude = new ArrayList<>();
static {
packagesToExclude.add("com.sun.proxy");
// these can be added if test suite code is run
packagesToExclude.add("org.junit");
packagesToExclude.add("org.apache.spark");
packagesToExclude.add("org.apache.sysml.test");
packagesToExclude.add("scala");
}
/**
* The base source directory to scan for classes to potentially load.
*/
private static final String BASE_SRC_DIR = "src/main";
/**
* The detected classes and their jar files, where the jar names are keys in
* a sorted map and sorted sets of the class names are the values in the
* sorted map.
*/
public static SortedMap> jarsAndClasses = new TreeMap<>();
/**
* The jar dependencies and their sizes for comparison purposes.
*/
public static SortedMap jarSizes = new TreeMap<>();
/**
* Dummy logger to fill in log4j info for things such as the jar sizes.
* Usually not needed.
*/
protected static Logger log = Logger.getLogger(BuildLite.class);
private static boolean includeAllCommonsMath3 = true;
/**
* Create lite jar file using the default path and file name as the
* destination. All commons-math3 classes will be included.
*
* @throws Exception
* if exception occurs building jar
*/
public static void createLiteJar() throws Exception {
createLiteJar(null, true);
}
/**
* Create lite jar file using the default path and file name as the
* destination, specifying whether all commons-math3 classes should be
* included in the jar or only the detected required subset.
*
* @param allCommonsMath3
* if true, include all commons-math3 classes. if false, include
* only required subset in jar built
* @throws Exception
* if exception occurs building jar
*/
public static void createLiteJar(boolean allCommonsMath3) throws Exception {
createLiteJar(null, allCommonsMath3);
}
/**
* Create lite jar file specifying the destination path and file name as a
* string.
*
* @param jarFileDestination
* the path and file name for the lite jar
* @param allCommonsMath3
* if true, include all commons-math3 classes. if false, include
* only required subset in jar built
* @throws Exception
* if exception occurs building jar
*/
public static void createLiteJar(String jarFileDestination, boolean allCommonsMath3) throws Exception {
if (jarFileDestination != null) {
liteJarLocation = jarFileDestination;
}
includeAllCommonsMath3 = allCommonsMath3;
scanJavaFilesForClassesToLoad();
List> loadedClasses = getLoadedClasses();
displayLoadedClasses(loadedClasses);
excludePackages(loadedClasses);
displayLoadedClasses(loadedClasses);
groupLoadedClassesByJarAndClass(loadedClasses);
List log4jClassPathNames = getLog4jClassPathNames();
displayLog4JClassPathNames(log4jClassPathNames);
List commonsMath3ClassPathNames = null;
if (includeAllCommonsMath3) {
commonsMath3ClassPathNames = getCommonsMath3ClassPathNames();
displayCommonsMath3ClassPathNames(commonsMath3ClassPathNames);
}
displayJarsAndClasses();
Set consolidatedClassPathNames = consolidateClassPathNames(loadedClasses, log4jClassPathNames,
commonsMath3ClassPathNames);
createJarFromConsolidatedClassPathNames(consolidatedClassPathNames);
createDependencySets();
displayJarSizes();
liteJarStats();
}
/**
* Exclude selected packages from the loaded classes.
*
* @param loadedClasses
* classes that have been loaded by the classloader
*/
private static void excludePackages(List> loadedClasses) {
System.out.println("\nExcluding selected packages");
int count = 0;
for (int i = 0; i < loadedClasses.size(); i++) {
Class clazz = loadedClasses.get(i);
String className = clazz.getName();
for (String packageToExclude : packagesToExclude) {
if (className.startsWith(packageToExclude)) {
System.out.println(" #" + ++count + ": Excluding " + className);
loadedClasses.remove(i);
i--;
}
}
}
}
/**
* Statistics about the lite jar such as jar size.
*/
private static void liteJarStats() {
File f = new File(liteJarLocation);
if (f.exists()) {
Long jarSize = f.length();
String jarSizeDisplay = FileUtils.byteCountToDisplaySize(jarSize);
System.out.println("\nFinished creating " + liteJarLocation + " (" + jarSizeDisplay + " ["
+ NumberFormat.getInstance().format(jarSize) + " bytes])");
} else {
System.out.println(liteJarLocation + " could not be found");
}
}
/**
* Consolidate the loaded classes and all the log4j classes and potentially
* all the commons-math3 classes.
*
* @param loadedClasses
* the loaded classes
* @param log4jClassPathNames
* the log4j class names
* @param commonsMath3ClassPathNames
* the commons-math3 class names
* @return the set of unique class names that combines the loaded classes
* and the log4j classes
*/
private static Set consolidateClassPathNames(List> loadedClasses, List log4jClassPathNames,
List commonsMath3ClassPathNames) {
SortedSet allClassPathNames = new TreeSet<>(log4jClassPathNames);
if (includeAllCommonsMath3) {
System.out.println("\nConsolidating loaded class names, log4j class names, and commons-math3 class names");
allClassPathNames.addAll(commonsMath3ClassPathNames);
} else {
System.out.println("\nConsolidating loaded class names and log4j class names");
}
for (Class clazz : loadedClasses) {
String loadedClassPathName = clazz.getName();
loadedClassPathName = loadedClassPathName.replace(".", "/");
loadedClassPathName = loadedClassPathName + ".class";
allClassPathNames.add(loadedClassPathName);
}
return allClassPathNames;
}
/**
* Build a lite jar based on the consolidated class names.
*
* @param consolidateClassPathNames
* the consolidated class names
* @throws IOException
* if an IOException occurs
*/
private static void createJarFromConsolidatedClassPathNames(Set consolidateClassPathNames)
throws IOException {
System.out.println("\nCreating " + liteJarLocation + " file");
ClassLoader cl = BuildLite.class.getClassLoader();
Manifest mf = new Manifest();
Attributes attr = mf.getMainAttributes();
attr.putValue("" + Attributes.Name.MANIFEST_VERSION, "1.0");
File file = new File(liteJarLocation);
try (FileOutputStream fos = new FileOutputStream(file); JarOutputStream jos = new JarOutputStream(fos, mf)) {
int numFilesWritten = 0;
for (String classPathName : consolidateClassPathNames) {
writeMessage(classPathName, ++numFilesWritten);
InputStream is = cl.getResourceAsStream(classPathName);
byte[] bytes = IOUtils.toByteArray(is);
JarEntry je = new JarEntry(classPathName);
jos.putNextEntry(je);
jos.write(bytes);
}
writeIdentifierFileToLiteJar(jos, ++numFilesWritten);
writeAdditionalResourcesToJar(jos, numFilesWritten);
}
}
/**
* Write an identifier file to the lite jar that can be used to identify
* that the lite jar is being used.
*
* @param jos
* output stream to the jar being written
* @param numFilesWritten
* the number of files written to the jar so far
* @throws IOException
* if an IOException occurs
*/
private static void writeIdentifierFileToLiteJar(JarOutputStream jos, int numFilesWritten) throws IOException {
writeMessage(LITE_JAR_IDENTIFIER_FILE, numFilesWritten);
JarEntry je = new JarEntry(LITE_JAR_IDENTIFIER_FILE);
jos.putNextEntry(je);
String created = "Created " + (new Date());
String userName = System.getProperty("user.name");
if (userName != null) {
created = created + " by " + userName;
}
jos.write(created.getBytes());
}
/**
* Write the additional resources to the jar.
*
* @param jos
* output stream to the jar being written
* @param numFilesWritten
* the number of files written to the jar so far
* @throws IOException
* if an IOException occurs
*/
private static void writeAdditionalResourcesToJar(JarOutputStream jos, int numFilesWritten) throws IOException {
for (String resource : additionalResources) {
writeMessage(resource, ++numFilesWritten);
JarEntry je = new JarEntry(resource);
jos.putNextEntry(je);
ClassLoader cl = BuildLite.class.getClassLoader();
InputStream is = cl.getResourceAsStream(resource);
byte[] bytes = IOUtils.toByteArray(is);
jos.write(bytes);
}
}
/**
* Output message about the resource being written to the lite jar.
*
* @param resource
* the path to the resource
* @param numFilesWritten
* the number of files written to the jar so far
*/
private static void writeMessage(String resource, int numFilesWritten) {
System.out.println(" #" + numFilesWritten + ": Writing " + resource + " to " + liteJarLocation);
}
/**
* Obtain a list of all log4j classes in the referenced log4j jar file.
*
* @return list of all the log4j classes in the referenced log4j jar file
* @throws IOException
* if an IOException occurs
* @throws ClassNotFoundException
* if a ClassNotFoundException occurs
*/
private static List getLog4jClassPathNames() throws IOException, ClassNotFoundException {
return getAllClassesInJar(ThrowableInformation.class);
}
/**
* Obtain a list of all commons-math3 classes in the referenced
* commons-math3 jar file.
*
* @return list of all the commons-math3 classes in the referenced
* commons-math3 jar file
* @throws IOException
* if an IOException occurs
* @throws ClassNotFoundException
* if a ClassNotFoundException occurs
*/
private static List getCommonsMath3ClassPathNames() throws IOException, ClassNotFoundException {
return getAllClassesInJar(Well1024a.class);
}
/**
* Obtain a list of all classes in a jar file corresponding to a referenced
* class.
*
* @param classInJarFile
* @return list of all the commons-math3 classes in the referenced
* commons-math3 jar file
* @throws IOException
* if an IOException occurs
* @throws ClassNotFoundException
* if a ClassNotFoundException occurs
*/
private static List getAllClassesInJar(Class classInJarFile) throws IOException, ClassNotFoundException {
List classPathNames = new ArrayList<>();
String jarLocation = classInJarFile.getProtectionDomain().getCodeSource().getLocation().getPath();
File f = new File(jarLocation);
try (FileInputStream fis = new FileInputStream(f);
JarArchiveInputStream jais = new JarArchiveInputStream(fis)) {
while (true) {
JarArchiveEntry jae = jais.getNextJarEntry();
if (jae == null) {
break;
}
String name = jae.getName();
if (name.endsWith(".class")) {
classPathNames.add(name);
}
}
}
String jarName = jarLocation.substring(jarLocation.lastIndexOf("/") + 1);
addClassPathNamesToJarsAndClasses(jarName, classPathNames);
return classPathNames;
}
/**
* Add jar and classes to the map of jars and their classes.
*
* @param log4jJar
* the log4j jar file
* @param classPathNames
* the list of log4j classes
*/
private static void addClassPathNamesToJarsAndClasses(String jar, List classPathNames) {
for (String classPathName : classPathNames) {
String className = classPathName.substring(0, classPathName.length() - 6);
className = className.replace("/", ".");
addJarAndClass(jar, className);
}
}
/**
* Dislay all the log4j classes
*
* @param log4jClassPathNames
* the list of log4j classes
*/
private static void displayLog4JClassPathNames(List log4jClassPathNames) {
int numClasses = 0;
System.out.println("\nAll log4j class files:");
for (String classPathName : log4jClassPathNames) {
numClasses++;
System.out.println(" #" + numClasses + ": " + classPathName);
}
}
/**
* Dislay all the commons-math3 classes
*
* @param commonsMath3ClassPathNames
* the list of commons-math3 classes
*/
private static void displayCommonsMath3ClassPathNames(List commonsMath3ClassPathNames) {
int numClasses = 0;
System.out.println("\nAll commons-math3 class files:");
for (String classPathName : commonsMath3ClassPathNames) {
numClasses++;
System.out.println(" #" + numClasses + ": " + classPathName);
}
}
/**
* Obtain a list of all the classes that have been loaded by the
* classloader.
*
* @return a list of all the classes that have been loaded by the
* classloader
* @throws NoSuchFieldException
* if NoSuchFieldException occurs
* @throws SecurityException
* if SecurityException occurs
* @throws IllegalArgumentException
* if IllegalArgumentException occurs
* @throws IllegalAccessException
* if IllegalAccessException occurs
*/
private static List> getLoadedClasses()
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
ClassLoader cl = BuildLite.class.getClassLoader();
Class clClazz = cl.getClass();
while (clClazz != java.lang.ClassLoader.class) {
clClazz = clClazz.getSuperclass();
}
Field f = clClazz.getDeclaredField("classes");
f.setAccessible(true);
@SuppressWarnings("unchecked")
Vector> classes = (Vector>) f.get(cl);
List> list = new ArrayList<>(classes);
return list;
}
/**
* Group the classes by jar file. Also, obtain the jar file sizes for
* comparison purposes.
*
* @param loadedClasses
* the list of loaded classes
*/
private static void groupLoadedClassesByJarAndClass(List> loadedClasses) {
for (Class clazz : loadedClasses) {
String pathToClass = getPathToClass(clazz);
if (pathToClass == null) {
addJarAndClass("?", clazz.getName());
} else if (pathToClass.endsWith(".jar")) {
String jarName = pathToClass.substring(pathToClass.lastIndexOf("/") + 1);
addJarAndClass(jarName, clazz.getName());
// for comparison purposes
if (!jarSizes.containsKey(jarName)) {
String jarPath = pathToClass;
File jarFile = new File(jarPath);
long fileLength = jarFile.length();
jarSizes.put(jarName, fileLength);
}
} else if (pathToClass.contains("systemml")) {
addJarAndClass("SystemML", clazz.getName());
} else {
addJarAndClass("Other", clazz.getName());
}
}
}
/**
* Add a jar and class to the map of jars to their sets of classes.
*
* @param jarName
* the name of the jar file
* @param className
* the name of the class
*/
private static void addJarAndClass(String jarName, String className) {
if (jarsAndClasses.containsKey(jarName)) {
SortedSet classNames = jarsAndClasses.get(jarName);
classNames.add(className);
} else {
SortedSet classNames = new TreeSet<>();
classNames.add(className);
jarsAndClasses.put(jarName, classNames);
}
}
/**
* Display the list of loaded classes.
*
* @param loadedClasses
* the list of loaded classes
*/
private static void displayLoadedClasses(List> loadedClasses) {
int numClasses = 0;
System.out.println("\nLoaded classes:");
for (Class clazz : loadedClasses) {
numClasses++;
System.out.println(" #" + numClasses + ": " + clazz + " (" + getPathToClass(clazz) + ")");
}
}
/**
* Obtain the file system path to the location of a class.
*
* @param clazz
* the class
* @return the file system path to the location of a class
*/
private static String getPathToClass(Class clazz) {
try {
return clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
} catch (java.lang.NullPointerException e) {
return null;
}
}
/**
* Display the required classes grouped by their jar files.
*
* @throws IOException
* if IOException occurs
*/
private static void displayJarsAndClasses() throws IOException {
ClassLoader cl = BuildLite.class.getClassLoader();
System.out.println("\nRequired Classes Grouped by Jar:");
Set jarNames = jarsAndClasses.keySet();
int numClasses = 0;
for (String jarName : jarNames) {
SortedSet classNames = jarsAndClasses.get(jarName);
StringBuilder sb = new StringBuilder();
int totalBytesUncompressed = 0;
for (String className : classNames) {
String classNamePath = className.replace(".", "/") + ".class";
InputStream is = cl.getResourceAsStream(classNamePath);
byte[] bytes = IOUtils.toByteArray(is);
int numBytes = bytes.length;
numClasses++;
sb.append(" #" + numClasses + " " + className + " [" + NumberFormat.getInstance().format(numBytes)
+ " bytes])\n");
totalBytesUncompressed += numBytes;
}
System.out.println("Jar: " + jarName + " [" + NumberFormat.getInstance().format(totalBytesUncompressed)
+ " bytes uncompressed]");
System.out.println(sb.toString());
}
}
/**
* Examine all java source files for additional classes to load. A
* relatively easy though not perfect way to do this is to look for imports
* of specified packages.
*
* @throws IOException
* if IOException occurs
* @throws ClassNotFoundException
* if ClassNotFoundException occurs
*/
private static void scanJavaFilesForClassesToLoad() throws IOException, ClassNotFoundException {
System.out.println("\nScanning java files for additional classes to load");
int totalMatches = 0;
SortedSet uniqueMatches = new TreeSet<>();
File base = new File(BASE_SRC_DIR);
List javaFiles = (List) FileUtils.listFiles(base, new String[] { "java" }, true);
for (File javaFile : javaFiles) {
String content = FileUtils.readFileToString(javaFile);
for (String additionalPackage : additionalPackages) {
String s = "import " + additionalPackage + "(.*?);";
Pattern p = Pattern.compile(s);
Matcher m = p.matcher(content);
while (m.find()) {
totalMatches++;
String match = m.group(1);
String matchClass = additionalPackage + match;
uniqueMatches.add(matchClass);
}
}
}
System.out.println("Total matches found from scan: " + totalMatches);
int uniqueMatchesSize = uniqueMatches.size();
System.out.println("Unique matches found from scan: " + uniqueMatchesSize);
int numMatches = 0;
for (String matchClass : uniqueMatches) {
Class clazz = Class.forName(matchClass);
String pathToClass = getPathToClass(clazz);
System.out.println(" #" + ++numMatches + ": Loaded " + clazz.getName() + " from " + pathToClass);
}
}
/**
* Display a list of the jar dependencies twice. The first display lists the
* jars, which can be useful when assembling information for the LICENSE
* file. The second display lists the jars and their sizes, which is useful
* for gauging the size decrease offered by the lite jar file.
*/
private static void displayJarSizes() {
System.out.println("\nIndividual Jar Dependencies (for Comparison):");
Set jarNames = jarSizes.keySet();
for (String jarName : jarNames) {
System.out.println(jarName);
}
System.out.println();
Long totalSize = 0L;
int count = 0;
for (String jarName : jarNames) {
Long jarSize = jarSizes.get(jarName);
String jarSizeDisplay = FileUtils.byteCountToDisplaySize(jarSize);
System.out.println(" #" + ++count + ": " + jarName + " (" + jarSizeDisplay + " ["
+ NumberFormat.getInstance().format(jarSize) + " bytes])");
totalSize = totalSize + jarSize;
}
String totalSizeDisplay = FileUtils.byteCountToDisplaySize(totalSize);
System.out.println("Total Size of Jar Dependencies: " + totalSizeDisplay + " ["
+ NumberFormat.getInstance().format(totalSize) + " bytes]");
}
/**
* Generate maven assembly dependency sets that can be used by the lite.xml
* assembly.
*
* @throws IOException
* if IOException occurs
*/
private static void createDependencySets() throws IOException {
System.out.println("\nCreating maven dependency sets");
StringBuilder sb = new StringBuilder();
sb.append("\t\n");
Set jarNames = jarsAndClasses.keySet();
for (String jarName : jarNames) {
String s = generateDependencySet(jarName, jarsAndClasses.get(jarName));
sb.append(s);
}
sb.append(generateSystemMLDependencySet());
sb.append("\t \n");
System.out.println(sb.toString());
final String liteXml = "src/assembly/lite.xml";
File f = new File(liteXml);
if (f.exists()) {
System.out.println("Found '" + liteXml + "', so updating dependencySets in the file.");
String s = FileUtils.readFileToString(f);
int start = s.indexOf("\t");
int end = s.indexOf(" ") + "".length() + 1;
String before = s.substring(0, start);
String after = s.substring(end);
String newS = before + sb.toString() + after;
FileUtils.writeStringToFile(f, newS);
}
}
/**
* Generate a maven assembly dependency set that can be used by the lite.xml
* assembly. Note that additional resources can be added to the jar by the
* additionalJarToFileMappingsForDependencySets entries.
*
* @param jarName
* the name of the jar file
* @param classNames
* a set of the classes in the jar file
* @return a string representation of the dependency set consisting of the
* resources in the jar file
*/
private static String generateDependencySet(String jarName, SortedSet classNames) {
StringBuilder sb = new StringBuilder();
String jarNameNoVersion = null;
if ("SystemML".equalsIgnoreCase(jarName)) {
jarNameNoVersion = "systemml";
return ""; // handle in generateSystemMLDependencySet()
} else {
jarNameNoVersion = jarName.substring(0, jarName.lastIndexOf("-"));
}
sb.append("\t\t\n");
sb.append("\t\t\t\n");
sb.append("\t\t\t\t*:" + jarNameNoVersion + " \n");
sb.append("\t\t\t \n");
sb.append("\t\t\t\n");
sb.append("\t\t\t\t\n");
Set jarsWithAdditionalFileMappings = additionalJarToFileMappingsForDependencySets.keySet();
if (jarsWithAdditionalFileMappings.contains(jarNameNoVersion)) {
SortedSet additionalResourceFiles = additionalJarToFileMappingsForDependencySets
.get(jarNameNoVersion);
for (String resourceFile : additionalResourceFiles) {
sb.append("\t\t\t\t\t" + resourceFile + " \n");
}
}
if (jarName.startsWith("log4j")) {
sb.append("\t\t\t\t\t**/*.class \n");
} else if (includeAllCommonsMath3 && (jarName.startsWith("commons-math3"))) {
sb.append("\t\t\t\t\t**/*.class \n");
} else {
for (String className : classNames) {
String classFileName = className.replace(".", "/") + ".class";
sb.append("\t\t\t\t\t" + classFileName + " \n");
}
}
sb.append("\t\t\t\t \n");
sb.append("\t\t\t \n");
sb.append("\t\t\tcompile \n");
sb.append("\t\t\ttrue \n");
sb.append("\t\t \n");
sb.append("\n");
return sb.toString();
}
private static String generateSystemMLDependencySet() {
StringBuilder sb = new StringBuilder();
sb.append("\t\t\n");
sb.append("\t\t\t\n");
sb.append("\t\t\t\t*:systemml* \n");
sb.append("\t\t\t \n");
sb.append("\t\t\t\n");
sb.append("\t\t\t\t\n");
sb.append("\t\t\t\t\tMETA-INF/DEPENDENCIES \n");
sb.append("\t\t\t\t\tMETA-INF/maven/** \n");
sb.append("\t\t\t\t\tkernels/** \n");
sb.append("\t\t\t\t\tlib/** \n");
sb.append("\t\t\t\t \n");
sb.append("\t\t\t \n");
sb.append("\t\t\t. \n");
sb.append("\t\t\tcompile \n");
sb.append("\t\t\ttrue \n");
sb.append("\t\t \n");
return sb.toString();
}
}