[
https://issues.apache.org/jira/browse/TWILL-215?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15859837#comment-15859837
]
Martin Serrano commented on TWILL-215:
--------------------------------------
Here are the diffs. With these changes, a user would get an exception at
submit time if a dependency could not be found. And all tests pass. But it
turns out there are many detected dependencies which are not used. In the
diffs below there a special cases for these. To be clear, I'm not proposing
these diffs as the solution, I just wanted to share how things shake out.
{code:language=diff}
diff --git
a/twill-core/src/main/java/org/apache/twill/internal/ApplicationBundler.java
b/twill-core/src/main/java/org/apache/twill/internal/ApplicationBundler.java
index 8f82dbd..2eaee84 100644
--- a/twill-core/src/main/java/org/apache/twill/internal/ApplicationBundler.java
+++ b/twill-core/src/main/java/org/apache/twill/internal/ApplicationBundler.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
+
import org.apache.twill.api.ClassAcceptor;
import org.apache.twill.filesystem.Location;
import org.apache.twill.internal.utils.Dependencies;
@@ -252,6 +253,30 @@ public final class ApplicationBundler {
Dependencies.findClassDependencies(classLoader, new ClassAcceptor() {
@Override
public boolean accept(String className, URL classUrl, URL classPathUrl) {
+
+ if (classPathUrl == null) {
+ /*
+ * ignore annotation runtime dependencies and the janino deps from
logback, and others.
+ * this just stops and exception being thrown if these don't exist
on classpath.
+ */
+ if (className.startsWith("javax.annotation") ||
+ className.contains("janino") ||
className.equals("javax.interceptor.InvocationContext")
+ || className.contains("ejb") ||
className.contains("javax.enterprise")
+ || className.contains("org.mockito.")) {
+ return false;
+ }
+ /* let findClassDependencies deal with anything else not found,
probably will throw an exception. */
+ return true;
+ }
+
+ /* - filter out gaffer (logback for gradle configuration
+ * - filter out logback IfAction which brings in commons-compiler
+ * even if the jar for these exists on the classpath it will not be
added.
+ */
+ if (className.contains("gaffer") ||
+ className.equals("ch.qos.logback.core.joran.conditional.IfAction")) {
+ return false;
+ }
if (bootstrapClassPaths.contains(classPathUrl.getFile())) {
return false;
}
diff --git
a/twill-core/src/main/java/org/apache/twill/internal/utils/Dependencies.java
b/twill-core/src/main/java/org/apache/twill/internal/utils/Dependencies.java
index eb55557..8e82950 100644
--- a/twill-core/src/main/java/org/apache/twill/internal/utils/Dependencies.java
+++ b/twill-core/src/main/java/org/apache/twill/internal/utils/Dependencies.java
@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
+
import org.apache.twill.api.ClassAcceptor;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
@@ -72,7 +73,9 @@ public final class Dependencies {
while (!classes.isEmpty()) {
String className = classes.remove();
URL classUrl = getClassURL(className, classLoader);
- if (classUrl == null) {
+
+ /* don't worry about inaccessible inner classes. */
+ if (classUrl == null && className.contains("$")) {
continue;
}
@@ -81,6 +84,10 @@ public final class Dependencies {
continue;
}
+ if (classUrl == null) {
+ throw new IOException("Dependency class " + className + " not found on
classpath");
+ }
+
try (InputStream is = classUrl.openStream()) {
// Visit the bytecode to lookup classes that the visiting class is
depended on.
new ClassReader(ByteStreams.toByteArray(is)).accept(new
DependencyClassVisitor(new DependencyAcceptor() {
@@ -106,6 +113,10 @@ public final class Dependencies {
}
private static URL getClassPathURL(String className, URL classUrl) {
+ if (classUrl == null) {
+ return null;
+ }
+
try {
if ("file".equals(classUrl.getProtocol())) {
String path = classUrl.getFile();
diff --git
a/twill-core/src/test/java/org/apache/twill/internal/utils/ApplicationBundlerTest.java
b/twill-core/src/test/java/org/apache/twill/internal/utils/ApplicationBundlerTest.java
index 4609ebd..8314434 100644
---
a/twill-core/src/test/java/org/apache/twill/internal/utils/ApplicationBundlerTest.java
+++
b/twill-core/src/test/java/org/apache/twill/internal/utils/ApplicationBundlerTest.java
@@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
+
import org.apache.twill.filesystem.LocalLocationFactory;
import org.apache.twill.filesystem.Location;
import org.apache.twill.internal.ApplicationBundler;
{code}
> Dependencies not on classpath lead to runtime startup error
> -----------------------------------------------------------
>
> Key: TWILL-215
> URL: https://issues.apache.org/jira/browse/TWILL-215
> Project: Apache Twill
> Issue Type: Bug
> Components: core
> Affects Versions: 0.9.0
> Reporter: Martin Serrano
> Priority: Critical
> Fix For: 0.10.0
>
>
> We do not use logback in our environment but it is a dependency of
> {{ApplicationMasterMain}}. When {{YarnTwillPreparer.createTwillJar}} is
> called in our environment, the logback jar is not on our classpath. For a
> class not in the classpath, the {{Dependencies.findClassDependencies}} method
> ignores it. This leads to a runtime startup error when the app master tries
> to start.
> This is easily fixed unless there some use case for ignoring the dependency
> when it is not on the classpath. An exception should be thrown and no yarn
> job should be submitted.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)