Java - How to import 'Reflections' class? - java

I'm trying to use Reflections classes as suggested here
stackoverflow.com/questions/12538761/
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes =
reflections.getSubTypesOf(SomeType.class);
Set<SomeType> someTypes = new HashSet<SomeType>(subTypes.size());
for (Class<? extends SubType> subType : subTypes) {
someTypes.add(subType.newInstance());
}
However, I cant seem to import the necessary package. NetBeans cant find it, and also I tried importing java.lang.reflections but it doesn't do it.
I can see java.lang.Class, but I don't see Reflections class anywhere.

Reflections isn't part of Java, it's a 3rd party library. First, you need to add the relevant Jar to your classpath. E.g., if you're using Maven, you could add the following dependency:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
Once you've done that, you need to import the Reflections class, as you noted. It is located in the org.reflections package:
import org.reflections.Reflections

It's a library https://github.com/ronmamo/reflections
Add it via Maven, Gradle or manually

Related

Is there an alternative for System.out.println without having to use System?

I am currently having to create a class called 'System'
and I can't put System.out.println because the System is always referring to the class.
How can I avoid this?
You can either:
use the fully qualified name java.lang.System
java.lang.System.out.println("Hello World!");
or;
statically import java.lang.System.out and use out.println:
// at the top of the file
import static java.lang.System.out;
...
out.println("Hello World!");
or;
Rename your class to something else, not System. Surely you can find a better, more specific name than that. For example, if you are making a game, call it GameSystem. Whatever you are making, try appending it to System to make XXXSystem.
For completeness, here's how you can create your own version of System.out without using the System class at all:
PrintStream out = new PrintStream(new FileOutputStream(FileDescriptor.out), true);
You should explore the options given in other answers first (like use the fully qualified class name java.lang.System or rename your System class)
If you're using Maven, add to your pom.xml the following dependency:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Now you can add the #Slf4j annotation to your class and use log.info("My message")
There are several levels of logging. Read more about the annotation here
I would suggest not to name your class like that, as already in java we have a class named System.
Alternatively, you can add a static import or use the fully qualified name of the Java class.
Static Import
import static java.lang.System.;*
But static imports can have ambiguity too, so I would suggest you to rename your class from System to something else, a bit related to your project.

Reflections and ByteBuddy

How can I use byte-buddy generated classes with "org.reflections"?
Example:
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.name("de.testing.SomeClass")
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
.load(getClass().getClassLoader(),ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
Now I want to use org.reflections to find all subtypes of Object inside a specific Package:
Reflections reflections = new Reflections("de.testing");
Set<Class<? extends Object>> objs = reflections.getSubTypesOf(Object.class);
for (Class clazz : objs ) {
log.info("{}",clazz.getName());
}
Any ideas?
As suggested in the comments, reflections scans the class path by querying class loaders for its resources. This does normally only work for standard class loaders whereas Byte Buddy creates classes in memory where they are not found using resource scanning.
You can work around this by storing Byte Buddy's classes in a jar file and loading this jar file manually using a URLClassLoader. Byte Buddy allows you to create a jar by .make().toJar( ... ). You can then provide this class loader to reflections which by default only scans the system class loader.
All this does however seem like quite a complex solution to a problem that could be easily solved by registering your types somewhere explicitly.

How can i get a list of all available annotations of some class

Is there a way I can show user a list of all available annotations related to some class , for example all annotations available with in hibernate , or under javax.persistence.
Like , to be more specific, When i write # in Eclipse and hit CtlSpace.
I get this list http://screencast.com/t/tLAVFdi46OiB
I want to show this whole list somewhere in my application's Interface.
there must be some where this list is coming from , From where i can fetch this list .
Any idea
thanks
All annotations implement the Annotation interface. Therefore, you can try something like this to find all annotations in the org.hibernate package (see Reflections javadocs):
Reflections reflections = new Reflections("org.hibernate");
Set<Class<? extends Annotation>> annotations = reflections.getSubTypesOf(Annotation.class);
You'll need the Reflections library, which relies on Guava and Javassist. If you're using IntelliJ and gradle (which I suggest) you can include this in your gradle file:
compile 'org.reflections:reflections-maven:0.9.9-RC2'
compile 'com.google.guava:guava:18.0'
compile 'javassist:javassist:3.12.1.GA'

How to speed up the class scan via Reflection API in Java?

I use org.reflections library to scan ClassPath and get classes. Here is my code:
Reflections ref = new Reflections();
Set<Class<? extends Service>> classes = new HashSet<>();
for (Class<? extends Service> subType : ref.getSubTypesOf(Service.class)) {
if (!Modifier.isAbstract(subType.getModifiers())) {
classes.add(subType);
}
}
But I faced a problem. It takes too much time. At the same time I can not set a package
new Reflections("my.pack");
because I want to save an ability to add Service classes in the future. How can I accelerate this process? Is it possible to exclude rt.jar packs?
Use FilterBuilder to exclude java root package at least.
And it may help to specify SubTypesScanner as that's what you're doing.
Reflections ref = new Reflections(new SubTypesScanner(),
new FilterBuilder().excludePackage("java"));

Reflections could not get class type

I am using a third party library called Reflections (not to be mistaken with Java reflection) to search another jar for Classes that extend Foo using the following code:
Reflections reflections = new Reflections("com.example");
for(Class<? extends Foo> e : reflections.getSubTypesOf(Foo.class)) {
doSomething()
}
When I do this Reflections throws the following error:
org.reflections.ReflectionsException: could not get type for name com.example.ExtendsFoo
Does anyone know how to fix this cause I'm stumped?
Thanks in advance!
The problem may be due to not having a class loader that can resolve the name (even though it can resolve the subtype). This sounds contradictory, but I had the error message when I was building a Configuration and using ClasspathHelper.forClassLoader on an application- instantiated URLClassloader to figure out what to scan on the classpath, but not passing in said URLClassLoader into the Reflections configuration so that it could instantiate things correctly.
So you may want to try something along the lines of the following:
URLClassLoader urlcl = new URLClassLoader(urls);
Reflections reflections = new Reflections(
new ConfigurationBuilder().setUrls(
ClasspathHelper.forClassLoader(urlcl)
).addClassLoader(urlcl)
);
where urls is an array of URLS to the jars containing the classes you want to load. I was getting the same error as you if I did not have the final addClassLoader(...) call to the ConfigurationBuilder.
If this doesn't work, or is not applicable, it may be worth just setting a breakpoint in ReflectionsUtil.forName(String typeName, ClassLoader... classLoaders)) to see what is going on.
Take a look: https://code.google.com/p/reflections/issues/detail?id=163
Reflections (in its current version 0.9.9-RC1) doesn't re-throw exception correctly. That's why you may miss the true cause of the problem. In my case it was a broken .class file, which my default class loader failed to load and threw an exception. So, first of all, try to make sure that your class is truly loadable.
Scanning for classes is not easy with pure Java.
The spring framework offers a class called ClassPathScanningCandidateComponentProvider that can do what you need. The following example would find all subclasses of MyClass in the package org.example.package
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
provider.addIncludeFilter(new AssignableTypeFilter(MyClass.class));
// scan in org.example.package
Set<BeanDefinition> components = provider.findCandidateComponents("org/example/package");
for (BeanDefinition component : components)
{
This method has the additional benefit of using a bytecode analyzer to find the candidates which means it will not load all classes it scans.
Class cls = Class.forName(component.getBeanClassName());
// use class cls found
}
Fore more info read the link

Categories