Skip to content

Relocate client proxies for public third-party normal-scope… - #3501

Open
jamezp wants to merge 1 commit into
weld:6.0from
jamezp:WELD-2838-6.0
Open

Relocate client proxies for public third-party normal-scope…#3501
jamezp wants to merge 1 commit into
weld:6.0from
jamezp:WELD-2838-6.0

Conversation

@jamezp

@jamezp jamezp commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

…d beans to avoid requiring --add-opens.

resolves #3502
Upstream #3500

@jamezp
jamezp requested a review from manovotn as a code owner September 3, 2026 17:04
@jamezp
jamezp marked this pull request as draft September 3, 2026 17:06
@jamezp
jamezp marked this pull request as ready for review September 3, 2026 17:37
@manovotn

manovotn commented Sep 3, 2026

Copy link
Copy Markdown
Member

Thanks for the PR James, I will take a closer look tomorrow.

Just two remarks from the top of my head.
Firstly, please create GH issue over a JIRA - project now mentions using GH issues everywhere (at least I hope it does :)).
Secondly, some time ago a did a more thorough yet unfinished attempt to convert Weld into a more JMPS-friendly manner. See #3460
It might be worth picking that up again - back then I had other duties and worries that dragged me away from it.

I am curious to see what case you had for this as I recall I had issues actually testing this for in EE environment you have to assume servers would handle the modular layers themselves (assuming they handle them at all).

@jamezp

jamezp commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

That's my bad. I can close the Jira and create an GitHub issue. I even looked the the contributing guide and still filed a Jira 🤦

I'll have a look at #3460. I just went through the process of adding Java modules to RESTEasy. In my experience the biggest issue I had, and still have, is testing. surefire/failsafe aren't great at it because they patch the module system. Anyway, I'm happy to have a look at it.

If we feel solving it as a whole is better, we can definitely close this too. I was just working on resteasy/resteasy-vertx#108 when I found this.

@jamezp jamezp changed the title WELD-2836 Relocate client proxies for public third-party normal-scope… Relocate client proxies for public third-party normal-scope… Sep 3, 2026
… avoid requiring --add-opens.

resolves weld#3502
Signed-off-by: James R. Perkins <jperkins@ibm.com>
@manovotn

manovotn commented Sep 3, 2026

Copy link
Copy Markdown
Member

I'll have a look at #3460. I just went through the process of adding Java modules to RESTEasy. In my experience the biggest issue I had, and still have, is testing. surefire/failsafe aren't great at it because they patch the module system. Anyway, I'm happy to have a look at it.

I have to look at it myself to see where I left it.
Though I would be interested in hearing your take on how it should be done.
From what I recall, the biggest issue/question is that Weld has to create those proxies and those should usually reside inside the package of the original class and that causes some nuissance :-/

@jamezp

jamezp commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Yes. I can see where it could be really tricky for Weld. I'll definitely have a look and do some thinking. I'm already finding bugs in what I did for RESTEasy :)

@manovotn manovotn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weld already avoids this for java.* and jakarta.* types by relocating their proxies into org.jboss.weld.generated.proxies.*.

The java.* are there since forever and the reason is that it was never possible to (even with CL usage) define a new class inside java packages.
I do not know the origin of the jakarta.* exception but I assume it was due to some EE servers where placing the proxy there might lead to leaks as the Jakarta lib would not be unloaded with the deployed app but I am just guessing there.

The general idea is to always leave the proxy class in the same package that the proxied type belongs to because that's the only way package private access keeps working.Note that by package private, I mean not only the class itself but also any methods on it. If you relocate a client proxy of a public class that has a pack private method, you still end up with broken proxy because overrides of pack private methods won't work across packages!

Plus, ProxyFactory is a base for other than client proxies such as interceptor proxies which are genuine subclasses so the requirements are stricter there. I'm not sure this change would affect them, need to check it as well.

Comment thread impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java
proxyClassName = proxyClassName.replaceFirst(JAVA, WELD_PROXY_PREFIX);
} else if (proxyClassName.startsWith(JAKARTA)) {
proxyClassName = proxyClassName.replaceFirst(JAKARTA, WELD_PROXY_PREFIX);
} else if (bean != null && shouldRelocateProxy(bean.getBeanClass())) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bean.getBeanClass() likely isn't what you meant. For a producer bean, this will not return the class of the bean, but the declaring class of the producer.

I am not sure what would be the best approach to determine the right class. A simple approach could be:

            Class<?> target = (bean instanceof AbstractProducerBean)
                    ? ((AbstractProducerBean<?, ?, ?>) bean).getType()
                    : bean.getBeanClass();

But this is likely to still be incorrect for some edge cases such as custom Bean implementations.
There is quite complex derivation of the package name somewhere inside the createCompoundProxyName method.

A more robust approach would have to work with the proxyClassName which already contains derived name of the package and match against that.
Though I am wondering if it wouldn't be better to instead change the base logic that determines the package instead of attempting a relocation as an afterthought.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had originally tried the proxyClassName, but sometimes that was java.lang.Object and it was causing issues where it relocated beans it shouldn't because java.lang.Object is in the java.base module. However, now that I think about it, I don't know why that module wouldn't be open.

Anyway, I wouldn't doubt if the bean.getBeanClass() was wrong, it just fixed the failing tests I had :)

}
// Only relocate proxy when we have a public modifier as we cannot override package-private methods.
// package-private access is intentionally handled by defineWithMethodLookup
if (!Modifier.isPublic(originalType.getModifiers())) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this check is not enough as you only verify the class being public.
However, you can have a public class that has a package-private method in it. If you relocate a proxy for such class, you won't be able to delegate to said method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. We should check the class is accessible too.

The general idea isn't necessarily to avoid requiring --add-opens, it's just to avoid it for most cases. IoW, if you have a non-publicly accessible method (via the method or class), you need to add the --add-opens. This only "fixes issues" for public beans in a named module.

@manovotn

manovotn commented Sep 4, 2026

Copy link
Copy Markdown
Member

Generally, even if we adapt your suggestion, it would have to have careful checks to only allow this for client proxies of public classes with no pack private methods which is a very small improvement.

Any single class in a JAR that doesn't meet these requirement will trigger the need for add-opens anyway.

That also leads to an awkward behavior where a seemingly working application can start throwing errors on adding a single method. Or perhaps on adding an interceptor to a bean that previously had none.
Not to mention you'd now sometimes be using MethodHandles and sometimes the custom CL to define the same class based on env. setup which does feel brittle and hard to understand/debug in the future.

@mkouba @Ladicek a penny for your thoughts on changes like these? Some other pitfalls you can think of when placing proxies into other than the original package?

Also, my limited knowledge of JPMS leads me to believe that using frameworks such as Weld in a modular app means you should be adding add-opens instead of looking for ways of bypassing it. Though I know little of it and will be happy to be proven wrong :)

@jamezp

jamezp commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Generally, even if we adapt your suggestion, it would have to have careful checks to only allow this for client proxies of public classes with no pack private methods which is a very small improvement.

Any single class in a JAR that doesn't meet these requirement will trigger the need for add-opens anyway.

Yes, and to be honest this may not be worth it. Even though users should not rely on a proxy class name, I've definitely seen cases where they do. In a non Java module environment, that is fine. It gets trickier for module environments if we relocate the package name.

TBH I do find it kind of hacky and we can definitely look for other/better solutions. We can definitely make this a draft if that's better.

That also leads to an awkward behavior where a seemingly working application can start throwing errors on adding a single method. Or perhaps on adding an interceptor to a bean that previously had none. Not to mention you'd now sometimes be using MethodHandles and sometimes the custom CL to define the same class based on env. setup which does feel brittle and hard to understand/debug in the future.

I definitely agree here.

Also, my limited knowledge of JPMS leads me to believe that using frameworks such as Weld in a modular app means you should be adding add-opens instead of looking for ways of bypassing it. Though I know little of it and will be happy to be proven wrong :)

I know we talked about this, but I'll add it here too for others. The add-opens isn't necessarily bad. Where it feels awkward to me is when you want to inject third-party beans. If you're project is a server type of environment you've got to let users know they need to add the add-opens directive. Honestly, maybe not a big deal.

I saw this when I was working on https://github.com/resteasy/resteasy-vertx and trying to have a smoke test for the Java module descriptors. I allow inject these types:

  • io.vertx.core.Vertx
  • io.vertx.ext.web.Router
  • io.vertx.ext.web.RoutingContext

Without the add-opens or this fix you end up with something like:

org.jboss.weld.exceptions.WeldException: WELD-001524: Unable to load proxy class for bean Producer Method [Router] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @RequestScoped public dev.resteasy.vertx.cdi.VertxProducers.router()] with class class java.lang.Object
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:424)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.instantiateProxy(ProxyFactory.java:375)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.create(ProxyFactory.java:368)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyFactory.create(ClientProxyFactory.java:84)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyProvider.createClientProxy(ClientProxyProvider.java:207)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyProvider.createClientProxy(ClientProxyProvider.java:197)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyProvider$CreateClientProxy.apply(ClientProxyProvider.java:52)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyProvider$CreateClientProxy.apply(ClientProxyProvider.java:48)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.lambda$new$0(ReentrantMapBackedComputingCache.java:57)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.LazyValueHolder$1.computeValue(LazyValueHolder.java:32)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.LazyValueHolder.get(LazyValueHolder.java:46)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.getValue(ReentrantMapBackedComputingCache.java:74)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.getCastValue(ReentrantMapBackedComputingCache.java:80)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ClientProxyProvider.getClientProxy(ClientProxyProvider.java:232)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:720)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:817)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:91)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.Beans.injectBoundFields(Beans.java:357)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:368)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:49)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:126)
	at org.jboss.resteasy.cdi@7.0.4.Final/org.jboss.resteasy.cdi.JaxrsInjectionTarget.inject(JaxrsInjectionTarget.java:94)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:165)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:96)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:106)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.get(ContextualInstanceStrategy.java:192)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:101)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:136)
	at dev.resteasy.vertx.it/dev.resteasy.vertx.it.CdiContextInjectionTest$ContextResource$Proxy$_$$_WeldClientProxy.securityContext(Unknown Source)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:154)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:118)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:560)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:452)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:413)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:333)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:415)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:378)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:356)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:70)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:434)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$0(SynchronousDispatcher.java:245)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:159)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:333)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:162)
	at org.jboss.resteasy.core@7.0.4.Final/org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:234)
	at dev.resteasy.vertx.server@2.0.0.Beta3-SNAPSHOT/dev.resteasy.vertx.server.VertxRoutingContextHandler.service(VertxRoutingContextHandler.java:178)
	at dev.resteasy.vertx.server@2.0.0.Beta3-SNAPSHOT/dev.resteasy.vertx.server.VertxRoutingContextHandler.dispatch(VertxRoutingContextHandler.java:132)
	at dev.resteasy.vertx.server@2.0.0.Beta3-SNAPSHOT/dev.resteasy.vertx.server.VertxRoutingContextHandler.lambda$handle$0(VertxRoutingContextHandler.java:113)
	at io.vertx.core@5.1.7/io.vertx.core.Future.lambda$onComplete$1(Future.java:312)
	at io.vertx.core@5.1.7/io.vertx.core.impl.future.FutureImpl$ListenerArray.complete(FutureImpl.java:188)
	at io.vertx.core@5.1.7/io.vertx.core.impl.future.FutureBase$EmitResultTask.run(FutureBase.java:125)
	at io.vertx.core@5.1.7/io.vertx.core.impl.ContextBase.execute(ContextBase.java:96)
	at io.vertx.core@5.1.7/io.vertx.core.impl.future.FutureBase.emitResult(FutureBase.java:83)
	at io.vertx.core@5.1.7/io.vertx.core.impl.future.FutureImpl.completeInternal(FutureImpl.java:137)
	at io.vertx.core@5.1.7/io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:143)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.HttpEventHandler.handleEnd(HttpEventHandler.java:79)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.http1.Http1ServerRequest.onEnd(Http1ServerRequest.java:562)
	at io.vertx.core@5.1.7/io.vertx.core.impl.ContextBase.execute(ContextBase.java:112)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.http1.Http1ServerRequest.handleEnd(Http1ServerRequest.java:163)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.http1.Http1ServerConnection.onEnd(Http1ServerConnection.java:260)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.http1.Http1ServerConnection.handleMessage(Http1ServerConnection.java:208)
	at io.vertx.core@5.1.7/io.vertx.core.net.impl.VertxConnection.read(VertxConnection.java:309)
	at io.vertx.core@5.1.7/io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:170)
	at io.netty.transport@4.2.17.Final/io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
	at io.netty.transport@4.2.17.Final/io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
	at io.netty.codec.http@4.2.17.Final/io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:87)
	at io.netty.transport@4.2.17.Final/io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
	at io.netty.codec@4.2.17.Final/io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:361)
	at io.netty.codec@4.2.17.Final/io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:325)
	at io.netty.transport@4.2.17.Final/io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.tcp.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)
	at io.vertx.core@5.1.7/io.vertx.core.http.impl.tcp.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)
	at io.netty.transport@4.2.17.Final/io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.transport@4.2.17.Final/io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1429)
	at io.netty.transport@4.2.17.Final/io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:176)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.handle(AbstractNioChannel.java:445)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.NioIoHandler$DefaultNioRegistration.handle(NioIoHandler.java:388)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.NioIoHandler.processSelectedKey(NioIoHandler.java:596)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.NioIoHandler.processSelectedKeysPlain(NioIoHandler.java:541)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.NioIoHandler.processSelectedKeys(NioIoHandler.java:514)
	at io.netty.transport@4.2.17.Final/io.netty.channel.nio.NioIoHandler.run(NioIoHandler.java:484)
	at io.netty.transport@4.2.17.Final/io.netty.channel.SingleThreadIoEventLoop.runIo(SingleThreadIoEventLoop.java:225)
	at io.netty.transport@4.2.17.Final/io.netty.channel.SingleThreadIoEventLoop.run(SingleThreadIoEventLoop.java:196)
	at io.netty.common@4.2.17.Final/io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1204)
	at io.netty.common@4.2.17.Final/io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.common@4.2.17.Final/io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: java.lang.RuntimeException: java.lang.IllegalAccessException: module io.vertx.web does not open io.vertx.ext.web to module weld.core.impl
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.util.WeldDefaultProxyServices.defineWithMethodLookup(WeldDefaultProxyServices.java:155)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.util.WeldDefaultProxyServices.defineClass(WeldDefaultProxyServices.java:62)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.toClass(ProxyFactory.java:975)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.createProxyClass(ProxyFactory.java:509)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:416)
	... 92 more
Caused by: java.lang.IllegalAccessException: module io.vertx.web does not open io.vertx.ext.web to module weld.core.impl
	at java.base/java.lang.invoke.MethodHandles.privateLookupIn(MethodHandles.java:268)
	at weld.core.impl@6.0.4.Final/org.jboss.weld.bean.proxy.util.WeldDefaultProxyServices.defineWithMethodLookup(WeldDefaultProxyServices.java:152)
	... 96 more

The workaround, as you suggested to me, is to simply wrap the types in your own wrapper with your package name. This does seem to work, but I do wrap io.vertx.Vertx and I don't have an issue injecting that.

It's also fair to be realistic to know if this is even an issue for others. It would be in a true Java module environment, but using add-opens works just fine and I don't even know how common it is to use Java modules with Weld or really other Jakarta libraries. None of the application servers I'm aware of use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants