Why does sonar think annotating non-public methods with #Transactional is wrong? - sonarqube

We use aspect4J and compile time weaving. Its perfectly valid to annotate private methods with #Transactional, or at least that is what I thought. I am curious as to why sonar has the following rule:
Non-public methods should not be "#Transactional"
My guess is that sonar must be unaware that there are multiple ways to weave aspects and that the Spring default of using dynamic proxies is not the only way.
Its also interesting to note that this is of severity "critical".
Two questions:
1 - Is sonar wrong to assume that annotating a private method with #Transactional is wrong?
2 - If they are wrong how do I file a bug with the sonar team?

We have also faced with a "#Transactional" issue in interfaces that appears to be a false positive:
http://jira.sonarsource.com/browse/SONARJAVA-967
Upgrading java plugin to latest version (3.3) fixed the issue.
As about non-public methods of the class, there is specification ticket in "Active" state:
http://jira.sonarsource.com/browse/RSPEC-2230
Answering your second question, I guess, their jira (http://jira.sonarsource.com) is the main bug-tracking system of the project.

Related

How to make pf4j plugin beans injectable into Spring app

We are trying to utilize pf4j and pf4j-spring to provide a flexible application based on Spring.
Ideally, we would like to define Spring beans (#Service, #Repository and others) in plugins and inject them in the main application.
From what I can see, it seems to fail due to timing issues. Or in other words, Springs expects the beans to be available before the PluginManager gets instantiated.
There is an example repository that illustrates the issue on GitHub.
The question would be: Can I change something, so that Spring instantiates the PluginManager first? Is there another approach to make this work?
Note: Yes, we are aware of sbp. Unfortunately, it seems to be dead, and we didn't get it working properly either.

Opening bean declared in Configuration class

Recently I encountered strange problem with Spring, Kotlin and Spock. I have very simple project (spring-boot, spring-web). I have one Controller with few Beans injected to this Controller. Everything works just fine. Problem is in test. I am not able to mock any of those Beans. kotlin-spring/kotlin-allopen does not add open signature to beans defined in Configuration class. On the other hand if I change this declaration to #Component everything works fine.
Here is my build.gradle.kts plugin listing
plugins {
id("idea")
id("groovy")
id("maven-publish")
id("org.springframework.cloud.contract") version "2.2.5.RELEASE"
id("org.springframework.boot") version "2.4.1"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("jvm") version "1.4.21"
kotlin("plugin.spring") version "1.4.21"
kotlin("plugin.allopen") version "1.4.21"
}
This is error message:
Caused by: org.spockframework.mock.CannotCreateMockException: Cannot create mock for class *** because Java mocks cannot mock final classes. If the code under test is written in Groovy, use a Groovy mock.
I know that it says that I can use GroovyMock but I wanted to design my base class in test and I wanted to use #TestConfiguration class. So to mock those classes I wanted to use DetachedMockFactory.
Is there a way to configure Spock to be able to mock final classes from Kotlin? Or is there a way to tell kotlin-spring/kotlin-allopen to open classes defined as beans in Configuration class?
Edit:
My example project is here:
https://github.com/czyzniek/bank/tree/with-spock
I cannot help you fix the spock-mockable problem, maybe you want to ask the author for help. Recently I fixed a Maven issue in that project already, but now it seems like there is a ByteBuddy issue, trying to redefine an already loaded class which is impossible in the JVM. I am sure the maintainer can help you with that.
Meanwhile, like I suggested in a previous comment, switching to Sarek solves the problem, though. I created a corresponding pull request for you.
For now it uses the full Sarek agent, which is the default. If you add sarek-unfinal as a dependency instead of sarek and also make sure that you set the system property dev.sarek.agent.type=unfinal in your Gradle configuration for Spock tests, you can use the smaller unfinal agent without the rest of the Sarek functionality instead. As a Gradle noob I do not know how to configure that, though.
Update: There is no more need for the additional system property mentioned above. The latest Sarek snapshot auto-detects the unfinal agent (or any other of the 4 types of Sarek agents) when it is on the class path. I know you have decided to use spock-mockable, but I want to keep this answer up to date for reference. See this diff for what the pull request would look like now, especially this simple commit.
Please let me know if you have any issues using the snapshot version for now. If this is a commercial project and you need to build a release in which snapshot versions are forbidden at some point, I can publish an 1.0 or maybe a 0.8 or whatever on Maven Central. For now I just added the Maven Central snapshot repository (Sonatype OSS) to your build.
Thanks for help everybody! #kriegaex your solution works like a charm, thanks for that!
Regarding spock-mockable, I talked with author of this library and he figured out why spock-mockable could not work with my setup (GH issue). It was because of spock-spring extension. The root cause is that spock-spring extension was loaded before spock-mockable. When Spring/Spock wanted to create mocks from #TestConfiguration class it couldn't, because kotlin-spring plugin does not open classes declared as beans in a #Configuration class and spock-mockable was not loaded at this time. joke changed the way his extension is loaded, so right now both solutions spock-mockable and sarek work.
I believe that concludes my problem ;)

How to inject dependencies in Gradle Plugin in Gradle recommended way?

I am writing a custom plugin and to test it, I want to inject mock implementations. It is not just for testing but from API perspective too, I want to inject different implementations depending on the context. I am currently using Gradle 2.6 and I understand that it supports some form of Dependency Injection. I do not want to use Spring/Guice/HK2 since Gradle itself supports it. However, I am not able to find any information how to inject dependencies using Gradle 2.6 APIs.
For eg:
class CustomTask extends DefaultTask {
private SomeInterface interface
#Inject
CustomTask(SomeInterface interface) {}
#TaskAction
public void executeTask() {
interface.executeSomething()
}
}
So, essentially, I want to figure where to define bindings for different instances of SomeInterface and the mechanism to inject it into task or anywhere else like some custom classes.
Since this question was not closed, some information might still be useful for whoever runs into it.
I do not want to use Spring/Guice/HK2 since Gradle itself supports it.
You might have already seen the relevant discussion on the gradle forum.
https://discuss.gradle.org/t/dependency-injection-in-gradle-plugins/6538
We are currently working on this. Dependency injection is already available for internal Gradle services, but I'm guess you are wanting to inject your own collaborators. Our dependency injection will support this at some point.
As usually with Gradle, we can check whatever is in the oven.
https://github.com/gradle/gradle/tree/bd4fb1c396a695d55aeba9bc37e164a488c0b882/design-docs
This design document can give you a look into what one of the core maintainers thought is a good way to approach the problem. While it is not complete, I consider it quite valuable.
Unfortunately the document (along with the complete folder) has been removed on Sep 20, 2017 with the following message:
This has turned into a graveyard for ideas. It only serves to confuse
people at this point. We have found it more productive to either
use GitHub Epics and issues for smaller design questions
use Google Docs for larger topics (e.g. native publishing)
These documents quickly go out of date once a feature is implemented.
They are not a replacement for good user and code documentation.
Many of the documents are about features that we never ended up
implementing. Having those documents still around might lock us into a
certain way of thinking about a problem. Instead we should have a
fresh look at it when we actually want to start working on it.

Maven with Spring injection

I am new to maven. When I try to build my project which has spring injection, im getting the following error:
Rule:InstanceVariableThreadSafety Priority:1 A class extending RequestHandler
or Action or SessionBean contains instance variables. It may not be Threadsafe.
The code should be reviewed and validated by the application team Tech Lead..
Please help me to resolve this.
Thanks.
This rule is a customized one, probably written by the "tech lead" to prevent you from adding instances variables into singleton classes such as Struts 1 Actions, EJB Statless SessionBean, and (Tapestry ?) RequestHandler.
If you're injecting a service into an action, you're right and your tech lead should refine his rule. There may be some way to add service dependencies which do not fire the rule though, only the tech lead will now this (and the developpment guide if you have one...)

What are reasons for eclipselink failing to autodetect entity classes?

I'm running eclipselink in an OSGi container and my entity classes are in their own bundle.
I have repeatedly run into the problem that Eclipselink fails to autodetect the entity classes, resulting in "Xyz is not a known entity type" messages. This is painful to debug and my somewhat helpless approach is to more or less randomly tweak configuration files until it works.
I wish I knew a more systematic approach, but I don't seem to know enough about possible reasons for the problem. What could they be? Is there an overview of what happens in autodetection and what is required for it to work?
So if you ran into the problem yourself and were able to determine one specific reason, post it here, or vote it up when you already see it. That way we could produce a list of typical issues sorted by frequency. I'll add the ones I actually solved.
Facts I know:
eclipselink uses the OSGi extender pattern to listen for bundles registering and then sets them up
it supposedly uses the class loader for the bundle that defines the persistence unit, if you're using a persistence.xml for configuration, this is the bundle where that file should be located.
The eclipselink jpa is not able to persist objects of classes that extend entity classes. Those extended classes should be entity classes by itself.
The bundle with the entity classes doesn't have the correct JPA-PersistenceUnits header in its manifest. This header is how eclipselink finds out that there is a persistence unit to be processed.
If listing your classes explictly makes it work, the wrong / missing header was not your problem.
The entity class is not listed explicitly in the configuration of the persistence unit and the persistence.xml (or whatever config mechanism you use) doesn't set the exclude-unlisted-classes parameter to false (depending on whether you run Java SE or EE, it may be true by default).
If it helps to list your classes explicitly, this may be your problem.

Resources