Skip to content

Commit

Permalink
1450 fix cli templates dependencies (#1460)
Browse files Browse the repository at this point in the history
* #1450 added new integration test which uses a templates jar with a custom utility class and dependency

* fixed #1450
refactored cached-pom.xml logic into new createCachedPomFromJar method
added pom.xml to test templates project jar
made sure that cached-pom.xml stays isolated in temporary folder

* #1450 fixed extract jar error
added exception trace to unable to extract exception

* #1450 fixed class paths cache file reading on Linux
replaced codehaus.plexus.OS with new SystemUtil method
added new getOS method to SystemUtils
refactored registerPlugins and prependTemplatesClassloader
added new addURLsFromCachedClassPathsFile method to MavenUtil
added new generatePomFileHash method to MavenUtil
fixed some typos

* #1450 added a primitive int class variable to test maven project to trigger usage of lang3 ClassUtils
  • Loading branch information
jan-vcapgemini authored Jan 19, 2022
1 parent 48f365f commit e85aab4
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public class SampleDataEntity implements SampleData {
@Size(max = 30, min = 3)
private String mail;

@Column(name = "PRIMITVEINT")
private int primitiveInt;

private static final long serialVersionUID = 1L;

/**
Expand Down Expand Up @@ -115,4 +118,12 @@ public void setModificationCounter(int modificationCounter) {

}

public int getPrimitiveInt() {
return this.primitiveInt;
}

public void setPrimitiveInt(int primitiveInt) {
this.primitiveInt = primitiveInt;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import org.codehaus.plexus.util.Os;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -31,7 +27,6 @@
import com.devonfw.cobigen.impl.CobiGenFactory;
import com.devonfw.cobigen.impl.extension.ClassServiceLoader;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;

/**
* Utilities class for CobiGen related operations. For instance, it creates a new CobiGen instance and registers all the
Expand Down Expand Up @@ -83,36 +78,17 @@ public static ClassLoader registerPlugins() {

Path rootCLIPath = getCliHomePath();
File pomFile = extractArtificialPom();
String pomFileHash;
try {
pomFileHash = com.google.common.io.Files.asByteSource(pomFile).hash(Hashing.murmur3_128()).toString();
} catch (IOException e) {
LOG.warn("Could not calculate hash of {}", pomFile.getAbsolutePath());
pomFileHash = "";
}

String pomFileHash = MavenUtil.generatePomFileHash(pomFile.toPath());

Path cpFile = rootCLIPath.resolve(String.format(MavenConstants.CLASSPATH_CACHE_FILE, pomFileHash));

if (!Files.exists(cpFile)) {
MavenUtil.cacheMavenClassPath(pomFile.toPath(), cpFile);
}
// Read classPath.txt file and add to the class path all dependencies
try (Stream<String> fileLinesStream = Files.lines(cpFile)) {
URL[] classpathEntries = fileLinesStream
.flatMap(e -> Arrays.stream(e.split(Os.isFamily(Os.FAMILY_WINDOWS) ? ";" : ":"))).map(path -> {
try {
return new File(path).toURI().toURL();
} catch (MalformedURLException e) {
LOG.error("URL of classpath entry {} is malformed", path, e);
}
return null;
}).toArray(size -> new URL[size]);
URLClassLoader cobigenClassLoader = new URLClassLoader(classpathEntries,
Thread.currentThread().getContextClassLoader());
ClassServiceLoader.lookupServices(cobigenClassLoader);
return cobigenClassLoader;
} catch (IOException e) {
throw new CobiGenRuntimeException("Unable to read " + cpFile, e);
}
URLClassLoader cobigenClassLoader = MavenUtil.addURLsFromCachedClassPathsFile(cpFile, pomFile.toPath(),
Thread.currentThread().getContextClassLoader());

ClassServiceLoader.lookupServices(cobigenClassLoader);
return cobigenClassLoader;

}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.devonfw.cobigen.api.util;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
Expand All @@ -22,6 +28,8 @@
import com.devonfw.cobigen.api.constants.MavenConstants;
import com.devonfw.cobigen.api.exception.CobiGenRuntimeException;
import com.google.common.collect.Lists;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteSource;

/**
* Utils to operate with maven artifacts
Expand Down Expand Up @@ -116,6 +124,61 @@ public static Path createCachedPomFromJar(Path pomFile, Path outputPath) {
return cachedPomXml;
}

/**
* Adds URLs from class paths cache file to URLClassLoader. If no class paths cache file was found a new one will be
* generated.
*
* @param classPathCacheFile the class paths cache file to read/create
* @param pomFile POM file that defines the needed CobiGen dependencies to build
* @param parentClassLoader parent ClassLoader
*
* @return URLClassLoader
*/
public static URLClassLoader addURLsFromCachedClassPathsFile(Path classPathCacheFile, Path pomFile,
ClassLoader parentClassLoader) {

if (!Files.exists(classPathCacheFile)) {
LOG.debug("Building class paths for maven configuration ...");
cacheMavenClassPath(pomFile, classPathCacheFile);
} else {
LOG.debug("Taking cached class paths from: {}", classPathCacheFile);
}

try (Stream<String> fileLinesStream = Files.lines(classPathCacheFile)) {
URL[] classPathEntries = fileLinesStream
.flatMap(e -> Arrays.stream(e.split(SystemUtil.getOS().contains("win") ? ";" : ":"))).map(path -> {
try {
return new File(path).toURI().toURL();
} catch (MalformedURLException e) {
LOG.error("URL of class path entry {} is malformed", path, e);
}
return null;
}).toArray(size -> new URL[size]);

return new URLClassLoader(classPathEntries, parentClassLoader);
} catch (IOException e) {
throw new CobiGenRuntimeException("Unable to read " + classPathCacheFile, e);
}
}

/**
* Generates a hash for the provided POM file
*
* @param pomFile to generate hash from
* @return String generated hash
*/
public static String generatePomFileHash(Path pomFile) {

String pomFileHash;
try {
pomFileHash = ByteSource.wrap(Files.readAllBytes(pomFile)).hash(Hashing.murmur3_128()).toString();
} catch (IOException e) {
LOG.warn("Could not calculate hash of {}", pomFile.toUri());
pomFileHash = "";
}
return pomFileHash;
}

/**
* @return the maven repository path
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public class SystemUtil {
*/
public static final String LINE_SEPARATOR = java.lang.System.getProperty("line.separator");

/** Current Operating System, the code is exectued on */
/** Current Operating System, the code is executed on */
private static final String OS = System.getProperty("os.name").toLowerCase();

/** Maven exectuable */
/** Maven executable */
private static Path MVN_EXEC = null;

/**
Expand Down Expand Up @@ -188,6 +188,16 @@ public static Path convertUnixPathToWinOnWin(String path) {
return returnVal;
}

/**
* Returns the Operating System type as a lower case string
*
* @return String Operating System type
*/
public static String getOS() {

return OS;
}

/**
* Determine mvn executable depending on the OS
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Collection;
import java.util.Formatter;
import java.util.List;
Expand All @@ -21,7 +20,6 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
Expand Down Expand Up @@ -65,8 +63,6 @@
import com.devonfw.cobigen.impl.util.ConfigurationClassLoaderUtil;
import com.devonfw.cobigen.impl.validator.InputValidator;
import com.google.common.collect.Maps;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteSource;

/**
* Generation processor. Caches calculations and thus should be newly created on each request.
Expand Down Expand Up @@ -272,13 +268,7 @@ private ClassLoader prependTemplatesClassloader(Path configLocation, ClassLoader
if (Files.exists(pomFile)) {
LOG.debug("Found templates to be configured by maven.");

String pomFileHash;
try {
pomFileHash = ByteSource.wrap(Files.readAllBytes(pomFile)).hash(Hashing.murmur3_128()).toString();
} catch (IOException e) {
LOG.warn("Could not calculate hash of {}", pomFile.toUri());
pomFileHash = "";
}
String pomFileHash = MavenUtil.generatePomFileHash(pomFile);

if (this.configurationHolder.isJarConfig()) {
cpCacheFile = configLocation
Expand All @@ -287,25 +277,7 @@ private ClassLoader prependTemplatesClassloader(Path configLocation, ClassLoader
cpCacheFile = configLocation.resolve(String.format(MavenConstants.CLASSPATH_CACHE_FILE, pomFileHash));
}

if (!Files.exists(cpCacheFile)) {
LOG.debug("Building classpath for maven templates configuration ...");
MavenUtil.cacheMavenClassPath(pomFile, cpCacheFile);
} else {
LOG.debug("Taking cached classpath from {}", cpCacheFile);
}

// Read classPath.txt file and add to the class path all dependencies
try (Stream<String> fileLines = Files.lines(cpCacheFile)) {
URL[] classpathEntries = fileLines.flatMap(e -> Arrays.stream(e.split(";"))).map(path -> {
try {
return new File(path).toURI().toURL();
} catch (MalformedURLException e) {
LOG.error("URL of classpath entry {} is malformed", path, e);
}
return null;
}).toArray(size -> new URL[size]);
combinedClassLoader = new URLClassLoader(classpathEntries, combinedClassLoader);
}
combinedClassLoader = MavenUtil.addURLsFromCachedClassPathsFile(cpCacheFile, pomFile, combinedClassLoader);
}

// prepend jar/compiled resources as well
Expand Down

0 comments on commit e85aab4

Please sign in to comment.