I write own DI/IoC library on java. I want to take classes which have some annotation (e.g. my own annotaion) in given package to scan, like in Spring IoC. But reflection from jdk is not appropriate, because i can't traverse through package. I took decision to use SimpleFileVisitor to take classes, but i don't want to use this "crutch". How to take classes with specific annotation in given package?
You must use Reflection lib form google.
Related
I want to change the package of classes that have been annotated with a particular annotation. I want to do this so that they can't be picked up by Jersey. I'm wondering if this is achievable within a Spring (Boot) application. If so, where is the best place to add this? I had originally wanted to do this in a ImportBeanDefinitionRegistrar so I could add an EnableXXX annotation on a config class, but I think that might be too late in the Spring lifecycle to redefine classes.
Yes, Byte Buddy allows you to change the name of any instrumented type. You can create an AgentBuilder to match all types that carry your annotation and change their package name using the DSL.
Do however note that any references to this class would not be updated automatically and other implications of a package change would be rather unpredictable. Generally, I would not recommend you to go down that route.
We have a system where we wanted to consume the implementation of our interfaces in a separate jar. The scenario is clients consume our work and provide their own implementation to override default implementation.
The question is what is the best way to bind/wire the actual implementation classes into our system?
One way is let spring wire the dependencies. It is currently not an option since all clients are not using spring.
Looked into some options like resolving interface implementation classes using reflection. Not very happy with this solution.
Another good old option is configure the class name in one of the property and let clients configure it. It looks good.
But wanted to find some elegant option if available.
Also any idea how SLF4J / EL resolves their implementations automatically?
I'd suggest you to use SPI (Service Provider Interface).
It requires creating file that enumerates all available implementations of specific service. This may be annoying. Fortunately you can use this open source library that does this work for you: http://code.google.com/p/spi/
Perhaps the Reflections library is what you are looking for.
Reflections scans your classpath, indexes the metadata, allows you to query it on runtime and may save and collect that information for many modules within your project.
Using Reflections you can query your metadata such as:
get all subtypes of some type
get all types/methods/fields annotated with some annotation, w/o annotation parameters matching
get all resources matching matching a regular expression
Are Java annotations used for adding functionality to Java code besides just adding documentation about what's going on in the code? What's the most advanced/complex functionality you could add to your code through an annotation?
Annotation are basically not more than a tag (with optional additional data) on a class/method/field. Other code (libraries or tools) can discover these tags and execute functionality dependant on the annotations found. I don't see a real limit on the complexity of the functionality possibly added by annotations. This can for example emulate AOP (adding functionality before or after a method with an annotation).
Annotations as such only add information (metadata) to a class.
One can easily build a system that uses that metadata to provide additional functionality, however.
For example you can use apt to generate classes based on the information provided by the annotation.
An annotation needs a tool to react to it. If such a tool does not exist the annotation is merely a notation. The "tool" can be an APT based agent or some piece of code that uses reflection (for instance, JUnit's #Test).
Several annotations are recognized by the Java compiler and thus have pre-defined semantics: #Override, #Deprecated, #Target.
I would understand Annotations as a way to document your code in a machine readable way.
For example in Hibernate you can specify the whole persistence information for your objects as annotations. This is directly readable for you and not in a distant xml file. But is also readable for the tool to generate configurations, database schemes etc.
I understand the purpose of class annotations, thanks to How and where are Annotations used in Java?. What is the purpose of package annotations, as described in this blog post and ยง7.4.1 of the Java Language Specification?
Why would you want to associate metadata with a package? What kinds of things could you do?
bnd tool (and maven-bundle-plugin) makes use of package annotations. Putting #Version and #Export annotation in package-info.java allows it to generate OSGi metadata.
javadoc uses package annotations.
JAXB uses package-level annotations, for example, to specify mapping of a Java type to XML Schema type package-wide. Package annotations are also used in JBoss's xml binding.
Struts 2 Convention plugin uses an annotation to specify a default interceptor for all actions in a package.
There are some package-level Hibernate Annotations. An example of those annotations' usage can be found here.
I suppose #Deprecated would make sense. And maybe something like #Generated if the whole package was generated by some tool from non-Java source. Or #Internal if this package is not part of a public API.
Maybe OSGi tools (where you need to declare the versions of your packages, and the packages you depend on) could make use of this, too.
Has anyone seen those in the wild?
Two reasons that I can think of:
Annotating special packages to let some aspects (for example using AspectJ) to weave the classes in them for specific functionality.
Annotating some packages that are to be read by some tools, for example for source, meta-data or other kinds of resource generation.
JAXB for example allows most annotations that are normally used on a type to be equally well applied to a package. The meaning in that case would be to specify the default for all classes in that package.
For example, if you want all properties of all classes in a package that are exposed via getter/setters to be mapped in XML you could specify #XmlAccessorType(XMLAccessType.PROPERTY) on each class or simply specify it on the package.
This is not the real purpose, but I'm using them as a workaround to avoid recompilation of the package-info.java files.
The problem is that javac (and the Ant task <javac>) creates no class file for the package-info.java if there is only documentation (the reason for their existence) and the package bla; statement, and that the ant task recompiles every file for which there is no (or an older) corresponding .class file.
Adding a dummy annotation there (like SuppressWarnings) had the effect that a package-info.class is produced and thus the file is not recompiled until changed again.
(Ant 1.8.0 solved this by creating an empty package-info.class, even if there was no annotation, but I'm using an older ant here.)
Test metadata -- that is metadata around test packages (unit tests or otherwise). You can ascribe various pieces of test metadata that are appropriate at the package level, such as: features, owners, versions, bugs/issues, etc. These could be refined at the class or method level, but having package-level definitions or defaults could be handy for brevity. I've utilized a variant of this approach (before the benefit of annotations).
A similar argument could be made for generalized code metadata around the same sorts of things: features, ownership, defects, historical information, etc.
Is there a way to add (or extend existing) classes at runtime in java. I'm stuck on a problem, in which I have to extend an existing class at runtime and add this to the classpath, so that this new class get picked up.
thanks,
There are a number of ways you could do this.
Compile source code at runtime using the javax.tools package and then load them using a ClassLoader.
If you are writing to interfaces, you can decorate classes with a Proxy.
Take the more complicated route of bytecode manipulation/generation using a technology like BCEL or ASM (the latter has more up-to-date support for language features, like annotations) and then load the class with a ClassLoader.
I imagine there are other options.
You might want to look at BCEL. Without any more information about what you need to do, it's tricky to give a more specific answer.
You should definitely write why you need this feature.
If you attempt to add or replace logic at runtime you might want to have a look at the scripting API and some actual implementations.