1

I have a simple Domain data class

@Document
data class Domain1Config(
    @Id val id: String = <prop_to_init>,
    val client: String,
    val size: String
) : Serializable

and I want to initialize its id property with a value that will be computed in a @Component annotated with @RequestScope

@Component
@RequestScope
class CurrentInstance() {

  private var currentInstance: String? = null

  fun getCurrentInstanceId() = currentInstance

  fun setCurrentInstanceId(instanceToSet: String) = {
     currentInstance = instanceToSet
  } 

}

Solutions that I've tried so far weren't optimal:

  • access to the ThreadLocal from a static function call during initialization of the property which avoids the issue of dependency injection into objects that are not instantiated by Spring => but ThreadLocal use means potential memory leaks
  • Spring's @Configurable with AspectJ Weaving to inject Spring Beans into unmanaged objects (tried with both load-time & compile-time weaving, very setup-heavy and none seem to work properly with Kotlin + Java version 11+) => I'm also not sure if it's recommended or it's good practice to go on the AspectJ Weaving way

Regarding the AspectJ compile-time weaving, here are the plugins I'm using at compile time:

        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin.version}</version>
            <configuration>
                <compilerPlugins>
                    <plugin>spring</plugin>
                </compilerPlugins>
                <jvmTarget>${java.version}</jvmTarget>
            </configuration>
            <!-- Automatically opens all classes that are necessary for Spring to work -->
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-allopen</artifactId>
                    <version>${kotlin.version}</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>kapt</id>
                    <goals>
                        <goal>kapt</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <sourceDir>src/main/kotlin</sourceDir>
                            <sourceDir>src/main/java</sourceDir>
                            <sourceDir>target/generated-sources/annotations</sourceDir>
                            <sourceDir>target/generated-sources/openapi/src/main/kotlin</sourceDir>
                        </sourceDirs>
                        <annotationProcessorPaths>
                            <annotationProcessorPath>
                                <groupId>org.mapstruct</groupId>
                                <artifactId>mapstruct-processor</artifactId>
                                <version>${mapstruct.version}</version>
                            </annotationProcessorPath>
                        </annotationProcessorPaths>
                    </configuration>
                </execution>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/main/kotlin</source>
                            <source>src/main/java</source>
                            <source>target/generated-sources/annotations</source>
                            <source>target/generated-sources/openapi/src/main/kotlin</source>
                        </sourceDirs>
                    </configuration>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/test/kotlin</source>
                            <source>src/test/java</source>
                        </sourceDirs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-configuration-processor</artifactId>
                        <version>${spring-boot.version}</version>
                    </path>
                    <!-- jhipster-needle-maven-add-annotation-processor -->
                </annotationProcessorPaths>
            </configuration>
            <executions>
                <!-- Replacing default-compile as it is treated specially by maven -->
                <execution>
                    <id>default-compile</id>
                    <phase>none</phase>
                </execution>
                <!-- Replacing default-testCompile as it is treated specially by maven -->
                <execution>
                    <id>default-testCompile</id>
                    <phase>none</phase>
                </execution>
                <execution>
                    <id>java-compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>java-test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.14.0</version>
                <configuration>
                    <forceAjcCompile>true</forceAjcCompile>
                    <sources />
                    <weaveDirectories>
                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
                    </weaveDirectories>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                    <complianceLevel>11</complianceLevel>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>1.9.7</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.9.7</version>
                    </dependency>
                </dependencies>
            </plugin>

I was wondering what would be a good/best practice to follow in this specific case?

redAce
  • 1,558
  • 4
  • 14
  • 24
  • I do not think that _"Spring's `@Configurable` with AspectJ weaving to inject Spring beans into unmanaged objects"_ is configuration-heavy. But for Java 9+, you cannot use the old Mojohaus AspectJ Maven Plugin 1.11. Either upgrade to 1.14.0 or use the more feature-rich and up-to-date [AspectJ.dev version](https://github.com/dev-aspectj/aspectj-maven-plugin). See also [here](https://stackoverflow.com/a/62213003/1082681) for an explanation. Then if you like, I can help you with that type of solution. – kriegaex Oct 28 '21 at 07:51
  • Yes I'd like to, thank you. I'm working on a project mixing both Java and Kotlin (I've updated my post with the plugins I'm using at compile time). I've already tried implementing AspectJ compile-time weaving but with no success. I was using 'aspectj-maven-plugin' v1.14.0 but had some compilation errors such as '[ERROR] around on staticinitialization of interface' on some interfaces implementing 'MongoRepository' – redAce Oct 28 '21 at 09:09
  • Probably your pointcuts are too broad and you need to limit their scope. The root cause could be something else too, though. Please publish an [MCVE](https://stackoverflow.com/help/mcve) on GitHub, then I can reproduce the problem and help you find a solution. Disclaimer: I am an AspectJ guy, not a Spring user. – kriegaex Oct 28 '21 at 11:42
  • I'll try to do so. But it will take me quite a bit of time. In the meantime can you please show me how I can limit the scope of compile-time weaving? I just want to apply it to one package. – redAce Nov 01 '21 at 10:00
  • How about you showing your aspect first? – kriegaex Nov 01 '21 at 10:13
  • I'm not using any aspect. Besides the compile-time configuration I've added to my post and enabling `@EnableSpringConfigured` https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/aspectj/EnableSpringConfigured.html – redAce Nov 02 '21 at 09:36
  • Fine. I am waiting for the MCVE then. I am in no hurry, take your time. – kriegaex Nov 02 '21 at 10:36
  • I was doing some basic tests building up the MCVE, but I was really surprised that compile-time weaving doesn't work in Intellij even when configuring ajc as the Java compiler in the IDE preferences with the aspectjtools library jar. It works fine when running the program via Maven though. Have you ever managed to get it working with Intellij? Because if it's not possible then I unfortunately can't continue on the AspectJ path. – redAce Nov 03 '21 at 17:22
  • Firstly, I also use IntelliJ IDEA and have no problems with AspectJ CTW there. Of course you have to install the AspectJ add-on, provided by JetBrains on the marketplace. Secondly, even if IntelliJ would not support AspectJ, why would you abandon it if it is the right tool doing the right job? Then you could still use Maven or configure your compiler and run configurations manually or write your own extension, if you felt so inclined. – kriegaex Nov 04 '21 at 08:56
  • Look, this is not a discussion forum but a Q/A platform. We debated too much in comments already. The reason is that you need help in solving a problem, but seem to be unable to too busy to provide an MCVE. To me that means that the issue is not important enough for you to work on and you have other priorities. It is really as simple as that. – kriegaex Nov 04 '21 at 08:59

0 Answers0