Reputation: 185
I am trying to get to the real classes of an instance that I injected via CDI. I only get a designation as a class name, which is composed of the name of the interface, a sequence of numbers and the character string "$Proxy$_$$_Weld$EnterpriseProxy$".
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TestProvider {
String value();
}
public interface TestConnector {
}
@TestProvider("TestConnector1")
@Stateless
public class Test1 implements TestConnector {
}
@Default
@TestProvider("TestConnector2")
@Stateless
public class Test12 implements TestConnector {
}
@Stateless
public class TestFactory {
@Inject
@Any
private Instance<TestConnector> testConnectors;
public TestConnector getConnector(String name) {
...
}
public Set<String> listAllTestConnectorNames(){
try {
Set<String> connectors = new HashSet<String>();
this.testConnectors.forEach(con -> {
System.out.println(con.getClass().getName());
for(Annotation x : con.getClass().getAnnotations()) {
if(x instanceof TestProvider) {
String name = ((TestProvider) x).value();
System.out.println(name);
connectors.add(name);
}
}
this.testConnectors.destroy(con);
});
return connectors;
} catch(Exception e) {
...
}
}
The function listAllTestConnectorNames should go through all the determined instances and return the value of the annotation TestProvider as a list. I would expect the following list.
But the instances that I received are of the type de.test.con1.TestConnector $ 710153185 $ Proxy $ _ $$ _ Weld $ EnterpriseProxy $ or de.test.con2.TestConnector $ 219965632 $ Proxy $ _ $$ _ Weld $ EnterpriseProxy $
How can I read out the values I am looking for?
Upvotes: 3
Views: 622
Reputation: 16196
Your TestConnector
instances are being proxied by Weld, probably because they are in a normal scope. This is fine and expected.
Your question, therefore, is: "Given a (Weld-defined) proxy class, how do I get the name of the 'real' class it is proxying?"
There is not a way that is guaranteed to work, but this way will work with Weld implementations of CDI:
Weld's proxy classes have the SYNTHETIC
flag set on them and in general extend the class they are proxying. I don't think this is guaranteed, but it has been true for many versions and many years now.
So if you do something like:
Class<?> c = proxyClass;
while (c.isSynthetic()) {
c = c.getSuperclass();
}
// Now c is the "real" class
System.out.println(c.getName()); // shouldn't be a proxy class name anymore
…you should be good.
Upvotes: 3