1818
1919import java .io .File ;
2020import java .io .IOException ;
21+ import java .net .URL ;
22+ import java .net .URLClassLoader ;
2123import java .nio .file .Files ;
2224import java .nio .file .Path ;
2325import java .nio .file .StandardOpenOption ;
26+ import java .util .ArrayList ;
2427import java .util .Collections ;
2528import java .util .List ;
29+ import java .util .concurrent .Callable ;
2630import java .util .function .Supplier ;
2731import java .util .stream .Stream ;
2832
29- import com .tngtech .archunit .ArchConfiguration ;
3033import com .tngtech .archunit .core .domain .JavaClasses ;
3134import com .tngtech .archunit .core .importer .ClassFileImporter ;
3235import com .tngtech .archunit .lang .ArchRule ;
@@ -84,17 +87,16 @@ private List<String> asDescriptions(List<ArchRule> rules) {
8487 }
8588
8689 @ 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 (() -> {
9192 JavaClasses javaClasses = new ClassFileImporter ().importPaths (classFilesPaths ());
9293 List <EvaluationResult > violations = evaluate (javaClasses ).filter (EvaluationResult ::hasViolation ).toList ();
9394 File outputFile = getOutputDirectory ().file ("failure-report.txt" ).get ().getAsFile ();
9495 writeViolationReport (violations , outputFile );
9596 if (!violations .isEmpty ()) {
9697 throw new VerificationException ("Architecture check failed. See '" + outputFile + "' for details." );
9798 }
99+ return null ;
98100 });
99101 }
100102
@@ -106,23 +108,33 @@ private Stream<EvaluationResult> evaluate(JavaClasses javaClasses) {
106108 return getRules ().get ().stream ().map ((rule ) -> rule .evaluate (javaClasses ));
107109 }
108110
109- private void writeViolationReport (List <EvaluationResult > violations , File outputFile ) {
111+ private void withCompileClasspath (Callable <?> callable ) throws Exception {
112+ ClassLoader previous = Thread .currentThread ().getContextClassLoader ();
110113 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 ());
116117 }
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 ();
119121 }
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 );
123124 }
124125 }
125126
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+
126138 public void setClasses (FileCollection classes ) {
127139 this .classes = classes ;
128140 }
0 commit comments