Find class marked with annotation of a specific value - java

I'm using this Java Reflections API that I'm finding quite convenient so far:
https://github.com/ronmamo/reflections
Find all classes marked with a specific annotation is dead easy, however, I can't figure out how to add a filter in the scanner to retrieve classes that have that annotation configured in a certain way.
For example, if I have three classes:
#Important(level="high")
public class HighlyImportant { }
#Important(level="medium")
public class ModeratelyImportant { }
#Important(level="low")
public class NotSoImportant { }
I can get all three classes by scanning for the #Important annotation, but how do I restrict that to only #Important(level=high) ?
Thanks

Related

Java custom annotation to make target class extend another class

In a spring boot project I'm working on, we have a lot of classes that extend Consumer, Processor, or Producer custom abstract classes. All these concrete extension classes are also annotated with #Component, #ConditionalOnProperty and usually #Profile as well.
I just started learning about Java annotations and was wondering if it's possible (at all) to simplify my above scenario by creating custom #Consumer, #Processor, and #Producer annotations, such that doing
#Consumer(profile = "some_profile", conditionalOnName = "some_name", conditionalOnValue = "some_value")
public class MyCustomConsumer {
// Abstract methods implementation
}
is the same as
#Component
#ConditionalOnProperty(name = "some_name", havingValue = "some_value")
#Profile("some_profile")
public class MyCustomConsumer extends Consumer {
// Abstract methods implementation
}
and the missing abstract methods inherited from Consumer are enforced on MyCustomConsumer (meaning the compiler will complain that those methods are not implemented).
Seems like a very long shot in getting something like this to work (as my research into Java annotations hasn't shown any viable option), but seeing how Lombok can add code to my code without modifying the file, I thought I'd ask.
Is this possible?

Is it OK to inject value directly inside Bean function?

I was wondering how to do dependency injection in the most effective way inside my code.
I have this code:
#Configuration
public class SomeName {
#Autowired
private Other other;
#Bean
public void method() {
other.someMethod();
// some code
}
}
Can this code be changed into the following code(other will be used only inside this function)?
#Configuration
public class SomeName {
#Bean
public void method(Other other) {
other.someMethod();
// some code
}
}
You should avoid #Autowired if possible and inject using a constructor or method.
Starting with Java 9 and java modules (project jigsaw) there are some strict rules that make it harder for your framework to change the values of a private field.
What Spring is doing in the first example is essentially that - it breaks encapsulation to change the value of a private value. (There is a way to overcome this with "opens" directive in module-info..)
You are also becoming dependent on the framework you are using and your code becomes harder to test compared to when using a simple setter.
You are also not explicitly declaring that your class depends on another class since I can easily instantiate it and "Other" will be null.
Some resources:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-autodetection (search for jigsaw)
https://blog.marcnuri.com/field-injection-is-not-recommended/
PS: You are probably missing #Configuration on your class

SonarQube. Detect cases of overriding methods which is annotated with the certain annotation in superclass. (this external API)

Now I'm trying to implement custom rule usin SonarQube for the next case. For example I have next class:
public class SuperClass{
#CannotOverrideAnnotation
protected void methodCanNotBeOverrided(){}
protected void methodCanBeOverrided(){}
}
And I'd like to detect cases where somebody tries to override methodCanNotBeOverrided.
public class ChildClass extend SuperClass{
protected void methodCanNotBeOverrided(){} // Noncompliant
protected void methodCanBeOverrided(){} //Compliant
}
Firstable, I think I have to visit every MethodTree and get owner of it like as:
#Override
protected void visitNode(MethodTree method){
Tree declaration = method.symbol().owner().declaration();
if (declaration.is(Tree.Kind.CLASS)) {
TypeTree superClass = ((ClassTree) declaration).superClass();
}
}
Ok, I've got superClass and I can extract fullyQualifiedName and use Reflection API.... but maybe there is other way to do it via SonarQube API?
I've found out that RetentionPolicy for this annotations equals to SOURCE, it means that I have no idea now how to implement rule, Reflection API cannot help me... Could anybody help me with ideas about this stuff.
Also I've found out that there is a very useful method in JavaSymbol.MethodJavaSymbol such as overriddenSymbol but this class doesn't belong org.sonar.plugins.java.api package and according to link I cannot use it.
org.sonar.plugins.java.api package containts the similar interface Symbol, but there is only common methods for all languages and there're not specific methods for Java.
I will be great for any help.
P.s. I'd like to emphasize that SuperClass - is an external library. I don't have an opportunity to change something there.

Is there a Java wrapper annotation?

Trying to find a way to wraps an object, which is auto generated based on some model with lots of getters and setters. For example:
class ObjectToWrap {
public int getIntA();
public int getIntB();
... // Tons of other getters
}
I have to create a wrapper that wraps this object and use some annotation that generates methods from ObjectToWrap for me. Code looks like the following:
class Wrapper {
private ObjectToWrap obj;
public int getIntA() {
return obj.getIntA();
}
public int getIntB() {
return obj.getIntB();
}
... // Tons of other getters
}
Is there an annotation to do this? I just don't want to make the code look lengthy.
Take a look at Project Lombok which has a #Delegate annotation which does exactly what you want.
#Delegate documentation
I think you would be able to do this:
import lombok.Delegate;
class Wrapper {
//the types field in the annotation says
//to only auto generate deleagate methods
//for only the public methods in the ObjectToWrap class
//and not any parent classes if ObjectToWrap extended something
#Delegate(types = ObjectToWrap.class)
private ObjectToWrap obj;
}
If you are using the maven build infrastructure with dependency management, you could have a dependent sub-project that collects the generated sources as-is (not as code). Another sub-project could then generate real sources out of them (source code transformation) as zip, which then could be imported by maven in the main project as pre-compile target.
On that basis you could use dynamic proxy classes, or even immediate generated classes.
The only other alternative would be to use the java scripting API, and do the business in JavaScript or so. Loosing the type safeness of java and lowering the software quality.
Unfortunately the alternative of hybrid usage of another JVM language I cannot consider productive. The very nice and powerful Scala still is too wild/complex/ticklish.

Unreferenced static inner classes treated differently by MOXy and the RI

Let's say I have the following two classes:
package example.model;
public class Model {
public static class Inner {}
public Other prop;
}
and
package example.model;
public class Other {
public static class Inner {}
public String prop;
}
and I create a JAXB context with JAXBContext.newInstance(example.model.Model.class).
With the default JAXB implementation from Java 6 this works without any annotations, and a generated model does not mention "inner". with EclipseLink I get a "Name collision. Two classes have the XML type with uri and name inner."
I know that making at least one of the inner classes #XmlTransient gets rid of the problem. What I would like to know is how this difference relates to the JAXB standard,
and, I guess, also if there is any other way to make MOXy ignore these classes like the default JAXB implementation does.
This appears to be a bug in EclipseLink JAXB (MOXy). We are currently working on a fix for the EclipseLink 2.3.3 and 2.4.0 streams. You can track our progress using the following link:
https://bugs.eclipse.org/374429
Once the fix is available you will be able to download a nightly build from the following link:
http://www.eclipse.org/eclipselink/downloads/nightly.php
Workaround
As you mention you can mark the static inner class with #XmlTransient.
package example.model;
public class Model {
#XmlTransient
public static class Inner {}
public Other prop;
}

Categories