eclipse-ee4j / eclipse-ee4j/yasson
Can't use Yasson in a Java EE 7 environment because java:comp/BeanManager is not jakarta.enterprise.inject.spi.BeanManager
- Dominant language
- Java
- Stars
- 218
- Forks
- 109
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 9
Description
**Describe the bug**
I'm trying to use JSON-B 2 (from Jakarta EE 9) and Yasson 2 in an application that will be deployed on IBM WebSphere Application Server 9, which is a Java EE 7 environment. I know this is unusual, but it mostly works except for the below issue.
Yasson tries to use JNDI to lookup `java:comp/BeanManager` and use it if it exists. The first problem is that `jakarta.enterprise.inject.spi.BeanManager` is not in the classpath, so we get a NoClassDefFoundError:
```
Caused by: java.lang.NoClassDefFoundError: jakarta/enterprise/inject/spi/BeanManager
at org.eclipse.yasson.internal.components.BeanManagerInstanceCreator.(BeanManagerInstanceCreator.java:49)
at org.eclipse.yasson.internal.components.JsonbComponentInstanceCreatorFactory.getComponentInstanceCreator(JsonbComponentInstanceCreatorFactory.java:69)
at org.eclipse.yasson.internal.JsonbContext.initComponentInstanceCreator(JsonbContext.java:148)
at org.eclipse.yasson.internal.JsonbContext.(JsonbContext.java:64)
at org.eclipse.yasson.internal.JsonBinding.(JsonBinding.java:49)
at org.eclipse.yasson.internal.JsonBindingBuilder.build(JsonBindingBuilder.java:61)
at jakarta.json.bind.JsonbBuilder.create(JsonbBuilder.java:86)
at com.example.TestBean.(TestBean.java:11)
```
After adding `jakarta.enterprise:jakarta.enterprise.cdi-api` jars, we get a more understandable error:
```
Caused by: jakarta.json.bind.JsonbException: Internal error: beanManager instance should be of type 'interface jakarta.enterprise.inject.spi.BeanManager'
at org.eclipse.yasson.internal.components.BeanManagerInstanceCreator.(BeanManagerInstanceCreator.java:50)
at org.eclipse.yasson.internal.components.JsonbComponentInstanceCreatorFactory.getComponentInstanceCreator(JsonbComponentInstanceCreatorFactory.java:69)
at org.eclipse.yasson.internal.JsonbContext.initComponentInstanceCreator(JsonbContext.java:148)
at org.eclipse.yasson.internal.JsonbContext.(JsonbContext.java:64)
at org.eclipse.yasson.internal.JsonBinding.(JsonBinding.java:49)
at org.eclipse.yasson.internal.JsonBindingBuilder.build(JsonBindingBuilder.java:61)
at jakarta.json.bind.JsonbBuilder.create(JsonbBuilder.java:86)
at com.example.TestBean.(TestBean.java:11)
```
**To Reproduce**
Here's a simple maven project that reproduces the issue: [test-servlet.zip](https://github.com/eclipse-ee4j/yasson/files/10073274/test-servlet.zip)
**Expected behavior**
To fix this, I suggest changing [`JsonbComponentInstanceCreatorFactory`](https://github.com/eclipse-ee4j/yasson/blob/6e7ec79c54218a05342cbb65f5b150cc5892b7c2/src/main/java/org/eclipse/yasson/internal/components/JsonbComponentInstanceCreatorFactory.java#L58) as follows:
1. If `jakarta.enterprise.inject.spi.BeanManager` is **not in** the classpath, then it should skip trying to get a BeanManager from CDI or JNDI and jump directly to using `DefaultConstructorCreator`.
2. If `jakarta.enterprise.inject.spi.BeanManager` is **in** the classpath but `getJndiBeanManager` somehow returned a `javax.enterprise.inject.spi.BeanManager` instead (note the javax), then just ignore it and use `DefaultConstructorCreator`.
**System information:**
- OS: Linux
- Java Version: 8
- Yasson Version: 2.0.4
**Additional context**
I was also able to reproduce this error using [Open Liberty server](https://github.com/OpenLiberty/open-liberty) with the `javaee-7.0` feature enabled.
Contributor guide
Assessment
This issue has not been assessed yet.