Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ subprojects {
apply plugin: 'java'
apply plugin: 'info.solidsoft.pitest'

sourceCompatibility = '1.7'
targetCompatibility = '1.7'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

group = "co.paralleluniverse"
version = "1.0.4-SNAPSHOT"
version = "1.0.4-ullink3-SNAPSHOT"
status = "integration"
description = "Simple Java deployment"
ext.url = "https://github.com/puniverse/capsule"
Expand Down Expand Up @@ -112,9 +112,9 @@ subprojects {
// xml.destination = "${buildDir}/reports/jacoco/test/jacocoTestReport_${project.name}.xml"
}
}

// check.dependsOn jacocoTestReport

javadoc {
options.links = [ "http://docs.oracle.com/javase/7/docs/api/" ]
}
Expand All @@ -133,19 +133,21 @@ subprojects {
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
// }

task javancss(dependsOn: 'classes') << {
ant {
logging.level = LogLevel.INFO
taskdef(name:'javancss', classname:'javancss.JavancssAntTask', classpath: configurations.javancss.asPath)
javancss(
srcdir:'src/main/java',
abortOnFail:'true',
generateReport:'true',
packageMetrics:'true',
classMetrics:'false',
functionMetrics:'false'
// outputFile: reportName,
)
task javancss(dependsOn: 'classes') {
doLast {
ant {
logging.level = LogLevel.INFO
taskdef(name: 'javancss', classname: 'javancss.JavancssAntTask', classpath: configurations.javancss.asPath)
javancss(
srcdir: 'src/main/java',
abortOnFail: 'true',
generateReport: 'true',
packageMetrics: 'true',
classMetrics: 'false',
functionMetrics: 'false'
// outputFile: reportName,
)
}
}
}

Expand Down Expand Up @@ -249,7 +251,7 @@ task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
html.enabled = true
xml.enabled = true
csv.enabled = false
xml.destination = "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
//xml.destination = "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
}
}

Expand Down
82 changes: 62 additions & 20 deletions capsule/src/main/java/Capsule.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
Expand Down Expand Up @@ -382,7 +383,7 @@ public static final void main(String[] args) {

/**
* Alternative main entry point that is not using System.exit(), thus avoiding callers to be terminated
* in an unexpected way.
* in an unexpected way.
*
* @param args0 the command line arguments
* @return the exit code
Expand Down Expand Up @@ -1274,10 +1275,10 @@ private static void printHelp(boolean simple) {
}
}
}

void introspect(List<String> args) {
STDERR.println("Capsule " + VERSION);

final List<Class<? extends Capsule>> caplets = getCaplets();
STDERR.println("Caplets: ");
if (caplets.isEmpty())
Expand All @@ -1291,9 +1292,9 @@ void introspect(List<String> args) {
STDERR.println(" " + sb);
}
}

STDERR.println();

STDERR.println("Attributes");
for (Map.Entry<String, Object[]> entry : ATTRIBS.entrySet()) {
final String attrib = entry.getKey();
Expand All @@ -1303,7 +1304,7 @@ void introspect(List<String> args) {
if (entry.getValue()[ATTRIB_DESC] != null)
sb.append(" (").append(entry.getValue()[ATTRIB_DESC]).append(')');
sb.append(": ");

sb.append("\n\t");
final Entry<String, ?> attr = attr(attrib);
final Object value = getAttributeNoLookup(attr);
Expand Down Expand Up @@ -2176,10 +2177,13 @@ private boolean testAppCacheUpToDate(Path dir) throws IOException {
Path extractedFile = dir.resolve(TIMESTAMP_FILE_NAME);
if (!Files.exists(extractedFile))
return false;
Optional<String> extractedTimeOptional = Files.readAllLines(extractedFile).stream().findFirst();
if (!extractedTimeOptional.isPresent())
return false;
final FileTime extractedTime = FileTime.fromMillis(Long.decode(extractedTimeOptional.get()));
final FileTime jarTime = Files.getLastModifiedTime(getJarFile());
final FileTime extractedTime = Files.getLastModifiedTime(extractedFile);
final boolean fresh = extractedTime.compareTo(jarTime) >= 0;
log(LOG_DEBUG, "JAR timestamp: " + jarTime + " Cache timestamp: " + extractedTime + " (" + (fresh ? "fresh" : "stale") + ")");
final boolean fresh = extractedTime.compareTo(jarTime) != 0;
log(LOG_VERBOSE, "JAR timestamp: " + jarTime + " Cache timestamp: " + extractedTime + " (" + (fresh ? "fresh" : "stale") + ")");
return fresh;
}

Expand Down Expand Up @@ -2210,7 +2214,12 @@ private void markCache() throws IOException {
if (!oc.plainCache || oc.appDir == null || oc.cacheUpToDate)
return;
if (Files.isWritable(oc.appDir))
Files.createFile(oc.appDir.resolve(TIMESTAMP_FILE_NAME));
{
Path timestampFile = oc.appDir.resolve(TIMESTAMP_FILE_NAME);
Files.createFile(timestampFile);
long jarTime = Files.getLastModifiedTime(getJarFile()).toMillis();
Files.write(timestampFile, Collections.singleton(String.valueOf(jarTime)));
}
}

private void lockAppCache(Path dir) throws IOException {
Expand Down Expand Up @@ -2536,14 +2545,47 @@ private List<String> buildJVMArgs() {
for (String a : getAttribute(ATTR_JVM_ARGS)) {
a = a.trim();
if (!a.isEmpty() && !a.startsWith("-Xbootclasspath:") && !a.startsWith("-javaagent:"))
addJvmArg(toNativePath(expand(a)), jvmArgs);
a = expand(a);
if (!addJava9ModulesJvmArg(a, jvmArgs)) {
a = toNativePath(a);
jvmArgs.put(getJvmArgKey(a), a);
}
}

return new ArrayList<String>(jvmArgs.values());
}

private static void addJvmArg(String a, Map<String, String> args) {
args.put(getJvmArgKey(a), a);
private void addJvmArg(String a, Map<String, String> args) {
if (!addJava9ModulesJvmArg(a, args))
args.put(getJvmArgKey(a), a);
}

private static final Pattern JAVA_9_MODULES_ARGS_REGEX = Pattern.compile("--add-((modules)|(opens)|(exports)|(reads))(=(.*))?");
private String firstPartJava9ModulesArg = null;
/**
* Handle Java 9 Modules options with formats "--add-opens=java.base/java.lang=ALL-UNNAMED"
* or "--add-opens java.base/java.lang=ALL-UNNAMED". In this last case it will be 2 arguments
* to recombine.
* @return true if the argument is for Java 9 modules (for options that begin with "--add-")
*/
private boolean addJava9ModulesJvmArg(String arg, Map<String, String> args)
{
Matcher matcher = JAVA_9_MODULES_ARGS_REGEX.matcher(arg);
if (matcher.matches()) {
boolean oneArgWithModuleAndPackage = matcher.group(7) != null;
if (oneArgWithModuleAndPackage)
args.put(arg, arg);
else
firstPartJava9ModulesArg = arg;
return true;
}
if (firstPartJava9ModulesArg != null) {
String fullArg = firstPartJava9ModulesArg + "=" + arg;
args.put(fullArg, fullArg);
firstPartJava9ModulesArg = null;
return true;
}
return false;
}

private static String getJvmArgKey(String a) {
Expand Down Expand Up @@ -2818,7 +2860,7 @@ protected final <T> T getAttributeNoLookup(Entry<String, T> attr) {
throw new RuntimeException("Exception while getting attribute " + name(attr), e);
}
}

protected final <T> T getAttributeDefaultValue(Entry<String, T> attr) {
final Object[] conf = ATTRIBS.get(name(attr));
final T type = type(attr);
Expand Down Expand Up @@ -3462,7 +3504,7 @@ protected final List<Path> resolve(Object x) {
if (res == null)
throw new RuntimeException("Could not resolve " + x);
if (res.isEmpty())
log(LOG_VERBOSE, "WARNING resolve " + x + " was empty");
log(LOG_VERBOSE, "resolve " + x + " was empty");
return res;
}

Expand Down Expand Up @@ -4589,11 +4631,11 @@ static List<String> parseCommandLineArguments(final String str) {
final int NORMAL = 0,
IN_QUOTE = 1,
IN_DOUBLE_QUOTE = 2;

final StringTokenizer tok = new StringTokenizer(str, "\"\'\\ ", true);
final ArrayList<String> result = new ArrayList<>();
final StringBuilder current = new StringBuilder();

int state = NORMAL;
boolean lastTokenHasBeenQuoted = false;
while (tok.hasMoreTokens()) {
Expand Down Expand Up @@ -5557,10 +5599,10 @@ else if (method.getName().startsWith("getClassLoader"))
private void overridePlatformMBeanServer() {
try {
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();

if (platformMBeanServer instanceof com.sun.jmx.mbeanserver.JmxMBeanServer) {
final MBeanServer interceptor = (MBeanServer) Proxy.newProxyInstance(MY_CLASSLOADER, new Class<?>[]{MBeanServer.class}, this);

Field interceptorField = accessible(com.sun.jmx.mbeanserver.JmxMBeanServer.class.getDeclaredField("mbsInterceptor"));
// this.origMBeanServer = ((com.sun.jmx.mbeanserver.JmxMBeanServer) platformMBeanServer).getMBeanServerInterceptor();
this.origMBeanServer = (MBeanServer) interceptorField.get(platformMBeanServer);
Expand Down Expand Up @@ -5779,7 +5821,7 @@ private static String getCapsuleVersion(Class<?> cls) {
cls = cls.getSuperclass();
return getClassVersion(cls);
}

private static String getClassVersion(Class<?> cls) {
if (cls == null)
return null;
Expand Down
23 changes: 23 additions & 0 deletions capsule/src/test/java/CapsuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,29 @@ public void testJVMArgs() throws Exception {
assertTrue(getJvmArgs(pb).contains("-Xbar:120"));
}

@Test
public void testJava9JVMArgs() throws Exception {
props.setProperty("capsule.jvm.args", "--add-opens=java.base/java.security=ALL-UNNAMED --add-exports java.base/java.lang=ALL-UNNAMED");

Jar jar = newCapsuleJar()
.setAttribute("Application-Class", "com.acme.Foo")
.setAttribute("JVM-Args", "--add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED")
.addEntry("foo.jar", emptyInputStream());

List<String> args = list("hi", "there");
List<String> cmdLine = list("--add-exports=java.base/java.nio=ALL-UNNAMED");

Capsule capsule = newCapsule(jar);
ProcessBuilder pb = capsule.prepareForLaunch(cmdLine, args);

assert_().that(getJvmArgs(pb)).containsSequence(list(
"--add-opens=java.base/java.lang.reflect=ALL-UNNAMED",
"--add-opens=java.base/java.net=ALL-UNNAMED",
"--add-opens=java.base/java.security=ALL-UNNAMED",
"--add-exports=java.base/java.lang=ALL-UNNAMED",
"--add-exports=java.base/java.nio=ALL-UNNAMED"));
}

@Test
public void testAgents() throws Exception {
Jar jar = newCapsuleJar()
Expand Down
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6 changes: 6 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Thu Mar 26 18:44:20 CET 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
Loading