I totally agree with you. Constructor injection is always preferred over field injection, and you explained very well why. Circular dependencies are much easier to detect with constructor injection because the application will fail consistently at startup in subsequent builds. With field injection, this is not always true: sometimes the application builds and runs successfully, and sometimes it doesn’t.
Because of this unpredictability in field-injection-based applications, it is possible to run the test suite in a CI environment and have everything succeed. The compile compile the application again to deploy the artifacts and end up with a corrupted JAR.
In my experience, what I have seen most often is that when an application has one of these circular dependencies, if the build produces a “corrupted” JAR, it always fails at startup. But not every build produces a corrupted JAR. So, the failure can appear as "random", but it isn't.
Oh yes, the random corrupted JAR. I've been there!
Years ago we had a microservice that used @Autowired liberally, and had hidden circular dependencies. It used to work... mostly. And every time a corrupted JAR was produced, we just used to run the build again and hope that it doesn't happen again. The CI/CD process was a mess!
It was only when someone had the epiphany of figuring out the root cause and fixing the dependencies that things became stable.
Fun times!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I totally agree with you. Constructor injection is always preferred over field injection, and you explained very well why. Circular dependencies are much easier to detect with constructor injection because the application will fail consistently at startup in subsequent builds. With field injection, this is not always true: sometimes the application builds and runs successfully, and sometimes it doesn’t.
Because of this unpredictability in field-injection-based applications, it is possible to run the test suite in a CI environment and have everything succeed. The compile compile the application again to deploy the artifacts and end up with a corrupted JAR.
In my experience, what I have seen most often is that when an application has one of these circular dependencies, if the build produces a “corrupted” JAR, it always fails at startup. But not every build produces a corrupted JAR. So, the failure can appear as "random", but it isn't.
Thanks for sharing. Great article!
Oh yes, the random corrupted JAR. I've been there!
Years ago we had a microservice that used
@Autowiredliberally, and had hidden circular dependencies. It used to work... mostly. And every time a corrupted JAR was produced, we just used to run the build again and hope that it doesn't happen again. The CI/CD process was a mess!It was only when someone had the epiphany of figuring out the root cause and fixing the dependencies that things became stable.
Fun times!