Skip to content

Commit 4c60cdc

Browse files
committed
GH-408 - 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 5944f0e commit 4c60cdc

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.*;
@@ -45,6 +46,7 @@
4546
import com.tngtech.archunit.base.DescribedPredicate;
4647
import com.tngtech.archunit.core.domain.JavaClass;
4748
import com.tngtech.archunit.core.domain.JavaClasses;
49+
import com.tngtech.archunit.core.domain.properties.HasName;
4850
import com.tngtech.archunit.core.importer.ClassFileImporter;
4951
import com.tngtech.archunit.core.importer.ImportOption;
5052
import com.tngtech.archunit.lang.EvaluationResult;
@@ -64,6 +66,8 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
6466
private static final ImportOption IMPORT_OPTION = new ImportOption.DoNotIncludeTests();
6567
private static final boolean JGRAPHT_PRESENT = ClassUtils.isPresent("org.jgrapht.Graph",
6668
ApplicationModules.class.getClassLoader());
69+
private static final DescribedPredicate<HasName> IS_AOT_TYPE = nameContaining("__")
70+
.or(nameContaining("$$SpringCGLIB$$"));
6771

6872
static {
6973

@@ -98,7 +102,7 @@ protected ApplicationModules(ModulithMetadata metadata, Collection<String> packa
98102
this.allClasses = new ClassFileImporter() //
99103
.withImportOption(option) //
100104
.importPackages(packages) //
101-
.that(not(ignored));
105+
.that(not(ignored.or(IS_AOT_TYPE)));
102106

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

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-408
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)