-
Notifications
You must be signed in to change notification settings - Fork 41.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use of @ConditionalOnMissingClass and @ConditionalOnMissingBean on @Configuration classes may cause java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy #1065
Comments
It should be possible to use |
It's Spring's reading of the annotation that causes the problem. It uses |
We deprecated the |
While working on #1013 I had the same issue with You can reproduce by using the boot fork available in this branch alongside this stupid app You can switch the Could it be related to the way this configuration class is added? that is
|
This is worse than I thought. Methods on a configuration class annotated with either To be safe, if you use |
@wilkinsona Has a Spring Framework bug been raised for this yet? |
I don't think it is a bug in Spring, or at least not an urgent one. It's the same as |
I'm inclined to agree with Dave. I'll open an issue against Spring so that it can be discussed. I'm also going to open an issue against the JDK to see if they can make the exception that's thrown more helpful. It's worth noting that we also need to be careful with |
I've opened SPR-11874 |
Alright. Do we agree I should stick with my current setup and use the "name" attribute instead? I don't see any other way to prevent the bean to be created if the class is not available. |
That isn't optimal in my opinion. It's better to use |
Hi. Not sure if it relates to this or I should open a new issue: For our corporation it is not possible to use spring boot. We have to deploy using a deployment tool to Glassfish 3.1.2. But it fails. I describe everything here: Will there be a workaround for this? |
I don't think there's anything Spring Boot can do about your problem with GlassFish.. I agree with Dave's comment on StackOverflow: it's a bug in GlassFish. Judging by the log output in your SO post, GlassFish's annotation scanning is very brittle as it appears to rely on loading a class to scan its annotations. Using ASM and examining the byte code directly is one more robust approach. Perhaps things have improved in GlassFish 4? |
IIRC Glassfish 4 is a different CDI standard and I believe that standard allows for an app to opt out of classpath scanning for certain packages (e.g. org.springframework.boot). Probably Glassfish 3 does as well (but as a vendor extension). We'd be interested to know if you find that feature and report back. |
seems I can't disable the CDI of Glassfish 3.1.2. Foud out that CDI 1.1 would indeed allow such an operation: https://blogs.oracle.com/theaquarium/entry/default_cdi_enablement_in_java I tried to deploy this beans.xml file: <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="none">
<scan>
<exclude name="org.springframework.boot.*" />
</scan>
</beans> but still same error. I guess GF3 is using CDI 1.0. Glassfish 4 is not an alternative for us. Oracle won't commercially support GF4. So we will move away from GF3 anyhow. But not in the near future. |
That's pretty much what I thought. IIRC JBoss AS has the equivalent of beans.xml as a vendor extension in its CDI1.0 container (I forget which that is), so I thought maybe Glassfish had something similar. |
With SPR-11874 being fixed and the GlassFish issue outside of our control I'm going to close this one. |
Using a Class reference can cause reflection problems at runtime (see spring-projectsgh-1065). Closes spring-projectsgh-2674
@Configuration
classes are turned into beans and stored in the application context. Spring will sometimes query the class of every bean to see if it has been annotated with a particular annotation, for example to find@Controller
s or@Aspect
s. This is typically done withAnnotationUtils.findAnnotation(…)
which will fail with a very crypticjava.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
if any of the annotations it encounters refer to classes that cannot be loaded. This will always be the case with@ConditionalOnMissingClass
: the only way for the bean that represents the configuration to be in the application context is if the class that it refers to is missing. It may be the case for@ConditionalOnMissingBean
.To avoid problems with
@ConditionalOnMissingBean
it should either be used on@Bean
methods, or be protected with an@ConditionalOnClass
annotation. Flyway's auto-configuration is a good example of the latter:Note the
@ConditionalOnClass(Flyway.class)
onFlywayAutoConfiguration
that makes it safe to use@ConditionalOnMissingBean(Flyway.class)
on the nestedFlywayConfiguration
To avoid potential problems with
@ConditionalOnMissingClass
I think it has to either be on an@Bean
method or, if it's used on a class, then the class must be referred to by name, i.e. as a String, rather than as a Class. At the time of writing,SocialWebAutoConfiguration.AnonymousUserIdSourceConfig
is the only class-level user of@ConditionalOnMissingClass
where the class is referenced directly, rather than by name.The text was updated successfully, but these errors were encountered: