18
18
19
19
import java .io .File ;
20
20
import java .io .IOException ;
21
+ import java .net .URL ;
22
+ import java .net .URLClassLoader ;
21
23
import java .nio .file .Files ;
22
24
import java .nio .file .Path ;
23
25
import java .nio .file .StandardOpenOption ;
26
+ import java .util .ArrayList ;
24
27
import java .util .Collections ;
25
28
import java .util .List ;
29
+ import java .util .concurrent .Callable ;
26
30
import java .util .function .Supplier ;
27
31
import java .util .stream .Stream ;
28
32
29
- import com .tngtech .archunit .ArchConfiguration ;
30
33
import com .tngtech .archunit .core .domain .JavaClasses ;
31
34
import com .tngtech .archunit .core .importer .ClassFileImporter ;
32
35
import com .tngtech .archunit .lang .ArchRule ;
@@ -84,17 +87,16 @@ private List<String> asDescriptions(List<ArchRule> rules) {
84
87
}
85
88
86
89
@ TaskAction
87
- void checkArchitecture () {
88
- ArchConfiguration .withThreadLocalScope ((configuration ) -> {
89
- configuration .setClassResolver (CompileClasspathClassResolver .class );
90
- configuration .setProperty (CompileClasspathClassResolver .PROPERTY_NAME , getCompileClasspath ().getAsPath ());
90
+ void checkArchitecture () throws Exception {
91
+ withCompileClasspath (() -> {
91
92
JavaClasses javaClasses = new ClassFileImporter ().importPaths (classFilesPaths ());
92
93
List <EvaluationResult > violations = evaluate (javaClasses ).filter (EvaluationResult ::hasViolation ).toList ();
93
94
File outputFile = getOutputDirectory ().file ("failure-report.txt" ).get ().getAsFile ();
94
95
writeViolationReport (violations , outputFile );
95
96
if (!violations .isEmpty ()) {
96
97
throw new VerificationException ("Architecture check failed. See '" + outputFile + "' for details." );
97
98
}
99
+ return null ;
98
100
});
99
101
}
100
102
@@ -106,23 +108,33 @@ private Stream<EvaluationResult> evaluate(JavaClasses javaClasses) {
106
108
return getRules ().get ().stream ().map ((rule ) -> rule .evaluate (javaClasses ));
107
109
}
108
110
109
- private void writeViolationReport (List <EvaluationResult > violations , File outputFile ) {
111
+ private void withCompileClasspath (Callable <?> callable ) throws Exception {
112
+ ClassLoader previous = Thread .currentThread ().getContextClassLoader ();
110
113
try {
111
- Files .createDirectories (outputFile .getParentFile ().toPath ());
112
- StringBuilder report = new StringBuilder ();
113
- for (EvaluationResult violation : violations ) {
114
- report .append (violation .getFailureReport ());
115
- report .append (String .format ("%n" ));
114
+ List <URL > urls = new ArrayList <>();
115
+ for (File file : getCompileClasspath ().getFiles ()) {
116
+ urls .add (file .toURI ().toURL ());
116
117
}
117
- Files .writeString (outputFile .toPath (), report .toString (), StandardOpenOption .CREATE ,
118
- StandardOpenOption .TRUNCATE_EXISTING );
118
+ ClassLoader classLoader = new URLClassLoader (urls .toArray (new URL [0 ]), getClass ().getClassLoader ());
119
+ Thread .currentThread ().setContextClassLoader (classLoader );
120
+ callable .call ();
119
121
}
120
- catch (IOException ex ) {
121
- throw new VerificationException (
122
- "Failed to write violation report to '" + outputFile + "' " + ex .getMessage ());
122
+ finally {
123
+ Thread .currentThread ().setContextClassLoader (previous );
123
124
}
124
125
}
125
126
127
+ private void writeViolationReport (List <EvaluationResult > violations , File outputFile ) throws IOException {
128
+ Files .createDirectories (outputFile .getParentFile ().toPath ());
129
+ StringBuilder report = new StringBuilder ();
130
+ for (EvaluationResult violation : violations ) {
131
+ report .append (violation .getFailureReport ());
132
+ report .append (String .format ("%n" ));
133
+ }
134
+ Files .writeString (outputFile .toPath (), report .toString (), StandardOpenOption .CREATE ,
135
+ StandardOpenOption .TRUNCATE_EXISTING );
136
+ }
137
+
126
138
public void setClasses (FileCollection classes ) {
127
139
this .classes = classes ;
128
140
}
0 commit comments