Skip to content

Commit 5d703a5

Browse files
committed
GH-407 - Ignore Spring AOT generated types in architecture model.
We now explicitly exclude classes generated by Spring AOT in the architectural model. For technical reasons, they might introduce dependencies to application components considered module internals otherwise. Also, proxies generated do not need to be considered either.
1 parent 69ec01a commit 5d703a5

File tree

5 files changed

+65
-1
lines changed

5 files changed

+65
-1
lines changed

spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static com.tngtech.archunit.base.DescribedPredicate.*;
1919
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.*;
20+
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.*;
2021
import static java.util.stream.Collectors.*;
2122

2223
import java.util.*;
@@ -43,6 +44,7 @@
4344
import com.tngtech.archunit.base.DescribedPredicate;
4445
import com.tngtech.archunit.core.domain.JavaClass;
4546
import com.tngtech.archunit.core.domain.JavaClasses;
47+
import com.tngtech.archunit.core.domain.properties.HasName;
4648
import com.tngtech.archunit.core.importer.ClassFileImporter;
4749
import com.tngtech.archunit.core.importer.ImportOption;
4850
import com.tngtech.archunit.lang.EvaluationResult;
@@ -62,6 +64,8 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
6264
private static final ImportOption IMPORT_OPTION = new ImportOption.DoNotIncludeTests();
6365
private static final boolean JGRAPHT_PRESENT = ClassUtils.isPresent("org.jgrapht.Graph",
6466
ApplicationModules.class.getClassLoader());
67+
private static final DescribedPredicate<HasName> IS_AOT_TYPE = nameContaining("__")
68+
.or(nameContaining("$$SpringCGLIB$$"));
6569

6670
static {
6771

@@ -97,7 +101,7 @@ protected ApplicationModules(ModulithMetadata metadata, Collection<String> packa
97101
this.allClasses = new ClassFileImporter() //
98102
.withImportOption(option) //
99103
.importPackages(packages) //
100-
.that(not(ignored));
104+
.that(not(ignored.or(IS_AOT_TYPE)));
101105

102106
Classes classes = Classes.of(allClasses);
103107

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.acme.myproject.aot;
17+
18+
/**
19+
*
20+
* @author Oliver Drotbohm
21+
*/
22+
public class Some$$SpringCGLIB$$Proxy {
23+
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.acme.myproject.aot;
17+
18+
/**
19+
*
20+
* @author Oliver Drotbohm
21+
*/
22+
public class Spring__Aot {
23+
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package com.acme.myproject.aot;

spring-modulith-integration-test/src/test/java/org/springframework/modulith/core/ApplicationModulesIntegrationTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.junit.jupiter.api.Test;
3131

3232
import com.acme.myproject.Application;
33+
import com.acme.myproject.aot.Some$$SpringCGLIB$$Proxy;
34+
import com.acme.myproject.aot.Spring__Aot;
3335
import com.acme.myproject.complex.internal.FirstTypeBasedPort;
3436
import com.acme.myproject.complex.internal.SecondTypeBasePort;
3537
import com.acme.myproject.moduleA.ServiceComponentA;
@@ -185,6 +187,15 @@ void explicitEmptyAllowedModulesResultsInAllDependenciesRejected() {
185187
assertThat(third.getDeclaredDependencies(modules).isAllowedDependency(Fourth.class)).isTrue();
186188
}
187189

190+
@Test // GH-407
191+
void excludesSpringAOTGeneratedTypes() {
192+
193+
assertThat(modules.getModuleByName("aot")).hasValueSatisfying(it -> {
194+
assertThat(it.contains(Spring__Aot.class)).isFalse();
195+
assertThat(it.contains(Some$$SpringCGLIB$$Proxy.class)).isFalse();
196+
});
197+
}
198+
188199
private static void verifyNamedInterfaces(NamedInterfaces interfaces, String name, Class<?>... types) {
189200

190201
Stream.of(types).forEach(type -> {

0 commit comments

Comments
 (0)