Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jan 31 2019 15:34
    manovotn commented #1897
  • Jan 31 2019 15:33
    manovotn commented #1899
  • Jan 31 2019 15:33

    manovotn on master

    Upgrade SpotBugs versions, Supp… (compare)

  • Jan 31 2019 15:33
    manovotn closed #1898
  • Jan 31 2019 14:41
    nziakova commented #1899
  • Jan 31 2019 14:40
    nziakova commented #1899
  • Jan 31 2019 14:18
    nziakova commented #1899
  • Jan 31 2019 14:12
    nziakova review_requested #1899
  • Jan 31 2019 14:12
    nziakova opened #1899
  • Jan 31 2019 11:18
    JavaTesting1 commented #64
  • Jan 31 2019 10:20
    manovotn review_requested #1898
  • Jan 31 2019 10:20
    manovotn opened #1898
  • Jan 31 2019 09:14

    manovotn on master

    WELD-2517: Weld SE - fix Securi… (compare)

  • Jan 31 2019 09:14
    manovotn closed #1895
  • Jan 31 2019 09:01
    nziakova edited #1897
  • Jan 31 2019 09:01
    nziakova edited #1897
  • Jan 31 2019 09:00
    nziakova review_requested #1897
  • Jan 31 2019 08:58
    nziakova opened #1897
  • Jan 30 2019 12:51
    manovotn review_requested #1896
  • Jan 30 2019 12:51
    manovotn review_requested #1896
Matej Novotny
@manovotn
@mkouba what do you think?
@beikov how about we look at it from a different angle - what is the current problem that requires this change? Do you have a reproducer project that shows it?
With that I could discuss it with some other folks (more JMPS-skilled than me :)) and maybe find another way to do it?
Because I think the fact that Weld was defining all classes in their packages since forever isn't coincidental - evne in this discussion we can see several problems already and i think it is not a total sum.
Christian Beikov
@beikov
I'm a bit busy right now, but I'll try to create that example ASAP
Christian Beikov
@beikov

Beans are not picked up if they are in modules that are on the module path, but I don't require these modules in my module-info

Just fyi, I started a discussion on the jigsaw-dev mailing list about this and it seems that adding modules with --add-modules does the trick for me. I think the maven surefire plugin should do this automatically though. Anyway, here is the thread: https://mail.openjdk.java.net/pipermail/jigsaw-dev/2021-June/014679.html

Proxy creation requires to open up all packages to Weld, which requires ugly command line flags since I don't control the module-info of all libraries

This one there is still bothering me, but I will create a sample for this

Christian Beikov
@beikov
I saw you marked the issue as resolved with 3.1.8.Final, but that version is not yet on maven central. Do you have any ETA when it will hit central?
@manovotn
Matej Novotny
@manovotn

I saw you marked the issue as resolved with 3.1.8.Final, but that version is not yet on maven central.

Issues are resolved when a solution made it to the codebase, not when the release is out. 3.1.8.Final is not yet released.
It is scheduled to mid July, but might a week or two sooner depending on one issue for WFLY that I am just sorting out. Release scheduled times are usually here - https://issues.redhat.com/projects/WELD?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=released-unreleased

https://mail.openjdk.java.net/pipermail/jigsaw-dev/2021-June/014679.html

Interesting mail thread, thanks for sharing it!

This one there is still bothering me, but I will create a sample for this

Sure, a sample would be great. I was thinking if we could do something like a dedicated weld module that you would open up your packages against and this module would then be used by weld to basically perform proxy definition. However, this still requires opening packages (but only at one place) and I think the same issue would exist with deep reflection which is something CDI spec basically requires ATM - private methods/fields and so no.
Anyhow, a sample would be a great start to see what's going on and what we truly need :)

Christian Beikov
@beikov

Release scheduled times are usually here -

Thanks or the heads up!

Björn Kautler
@Vampire

Hm, I have interface A and classes implementing this interface A1, A2, and A3.
Then I inject these using

@Inject
private void setAvailableA(Instance<A> availableA) { ... }

If I do this in a "normal" project, I get instances of classes like A1$Proxy$_$$_WeldClientProxy, A2$Proxy$_$$_WeldClientProxy, and A3$Proxy$_$$_WeldClientProxy with A1, A2, and A3 respectively as super classes.
This is perfect and exactly what I need, as I later need to do instanceof checks on these for reasons.

Now a user of the lib I wrote uses this whole thing in a Spring Boot JAR context and suddenly things change.
All injected instances are of classes A$1234567890$Proxy$_$$_WeldClientProxywith the number different for each.
They only have Object as super class and implement the interface A.
The contextual instance is a proper one.
But of course in this situation my instanceof checks fail.

Now my question is, did I depend on an implementation detail / concidence / whatever and I must not do it that way, but instead give the thing to check into a method and do the instanceof check in the contextual instance, or is the fact that I relied on is a specified behavior and should work like I expected and it is a bug that it does not work properly in the Spring Boot context?

Matej Novotny
@manovotn

Hello, @Vampire

Now a user of the lib I wrote uses this whole thing in a Spring Boot JAR context and suddenly things change.

So, is there any integration between Spring Boot and CDI? Because Weld sure doesn't do anything in this regard and I think Spring has its own dep. injection.

classes like A1$Proxy$_$$_WeldClientProxy

This is the standard format of a class-backed bean that does require a client proxy. Note that CDI specification doesn't mandate any format, but this is what Weld does.

Matej Novotny
@manovotn

All injected instances are of classes A$1234567890$Proxy$_$$_WeldClientProxywith the number different for each.
They only have Object as super class and implement the interface A.

Here I have to do some guesswork. This format looks like something Weld would create for a producer method with a return type equal to just interface.
E.g. as if someone created:

@Produces
@ApplicationScoped //or any other normal scope
public A createA() {
  return somehowCreateImplOfA();
}

Now, I don't see a reason why Weld itself would suddenly do this. It looks more like there is some other framework that does this (it can register producers via extension etc).
You probably need to look at user's setup to see what's going on.

Matej Novotny
@manovotn

Now my question is, did I depend on an implementation detail ...

Basically, yes. For example, users can have extensions that change beans from class based to producers or swap them for alternatives etc. This can keep the bean functionally working just like it was before but the proxy/subclass creation process can change and so you shouldn't rely on it.

One thing you can do is get your hands on the actual contextual instance that is behind proxy. This is Weld-specific feature and if you can, I'd recommend you find another way. But if you want to go that way, then all proxied beans Weld creates implement `WeldClientProxy, an interface that implement a method allowing you to grab the contextual instance.
See https://github.com/weld/api/blob/master/weld/src/main/java/org/jboss/weld/proxy/WeldClientProxy.java

Björn Kautler
@Vampire

Ah, thanks for the insight @manovotn.
You didn't guess right, but that was valuable informatin and it indeed behaves like that too if I use a producer in the project where it works like expected otherwise.

I debugged and compared a bit and found out why the difference is there.
The user depended on and packaged a weld-se-shaded artifact, but didn't actually use it, but instead the weld-servlet that is available in the spring boot stuff.
weld-se by default sets ConfigurationKey.RELAXED_CONSTRUCTION to true while weld-servlet does not.
Out of habit I declare my beans with private contstructor to make it clear they should not be instantiated manually.
Now without the RELAXED_CONSTRUCTIONthe DefaultProxyInstantiator is used which complains about the private constructor and thus makes proxies for the injected interface instead.
On weld-se RELAXED_CONSTRUCTION is true and thus the UnsafeProxyInstantiator is used which behaved as I expected it to for non-produced beans.

In the project where it didn't work as expected, if I set system property org.jboss.weld.construction.relaxed to true or add the META-INF/org.jboss.weld.enableUnsafeProxies marker file it also uses the UnsafeProxyInstantiator there and works as expected (as long as no producer is used).

I will change my logic to do it in a different way that is also compatible with produced beans,
but I nevertheless have three questions left for now:

  • Is using the META-INF/org.jboss.weld.enableUnsafeProxies marker file deprecated like the property org.jboss.weld.proxy.unsafeand one should use the org.jboss.weld.construction.relaxed property instead or is using the marker file fine?
  • Is it bad practice, good practice, or doesn't matter to have private constructors in the beans?
  • Is it WELD specific that it works with private constructors, or is this mandated by the CDI Standard?
Matej Novotny
@manovotn

@Vampire glad you found the cause. Here are some answers.

Is using the META-INF/org.jboss.weld.enableUnsafeProxies marker file deprecated like the property org.jboss.weld.proxy.unsafe and one should use the org.jboss.weld.construction.relaxed property instead or is using the marker file fine?

Unsafe property is deprecated in all ways and not even (deliberately) documented in latest versions, so relaxed construction it is.
Recommended way to pass in properties is via weld.properties file.
A side note - not even relaxed construction is recommended if you can avoid it. I am not sure from the top of my head what the impl is, but I think it involves some unsafe anyway (as there is no other way, really) and with late Java versions, a lot of Unsafe has been lifted or changed putting this option in a risk of being unimplementable in some near future should they change it. I would have to check how we do that once I am back from PTO...
But I think the fallback is this class used is this - https://github.com/weld/core/blob/master/impl/src/main/java/org/jboss/weld/bean/proxy/UnsafeProxyInstantiator.java

Is it bad practice, good practice, or doesn't matter to have private constructors in the beans?

Bad practice. We have to work around Java language limitations to be able to create proxies and/or interceptor subclasses. It is mainly intended for when you absolutely have to use some code you have no control over (3rd party lib) and where you need those classes as beans.

Is it WELD specific that it works with private constructors, or is this mandated by the CDI Standard?

Totally Weld specific. Specification says the you actually have to have a no-arg constructor for bean to be proxyable. See https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#unproxyable

So all in all, you should have beans with non-private no args constructor as soon as you want it proxied. Else we have to workaround either accessibility rights (if it is there but it's private) or have to find even hackier ways to instantiate the object.
Though I have no idea why is relaxed construction by default enabled in SE...

Björn Kautler
@Vampire
Thanks, that clears up a lot, so I have to get rid of that habit.
Christian Beikov
@beikov
@manovotn I created a sample app that shows the problem
If you look into the argLine section of the maven-surefire-plugin, you can see that I need to add various add-opens and add-reads flags which IMO shouldn't be necessary
at least not when proxying an interface. for proxying classes, I can see why this might be necessary, but even then, it would be awesome if we wouldn't need these flags
the critical part is, that the interface is defined in a module that isn't open
Matej Novotny
@manovotn
Thanks! I'll check this in the coming days.
Matej Novotny
@manovotn
I am being delayed by other issues and tasks but don't worry, the reproducer is still on my TODO list and isn't going to vanish :-)
Dmitrii Tikhomirov
@treblereel
Hello all, i need help with import jakarta.enterprise.inject.Typed, can't understand how it works
Matej Novotny
@manovotn

Hello, @treblereel
Beans are identifiable by the set of their types and their qualifiers. These are then matched against injection point to determine where to inject which bean. Normally, types are taken from the Java class backing the bean (or a return value of producer method) and the superclasses and interfaces. Not all types are considered legal though, see this part of specification.
Now, with @Typed, you can manually adjust the set of type each bean has and filter out any types you do not want. This will directly affect where you can inject the given bean. This part of specification described it.

In short, you don't usually need to use @Typed at all; it is just a tool allowing you to tailor bean types for some specific cases where you'd otherwise have ambiguous resolution issue or other problems. Hope this makes it clearer :)

Christian Beikov
@beikov
@manovotn I hope you don't forget about my issue :)
By the way, I ran into another one in a Gradle project. When running modular tests on gradle, I realized that the resources are in a different directory than the class files, so I thought about using --patch-module but apparently this doesn't work for Weld
Weld does not recognize that the module has a beans.xml file and simply doesn't consider it as bean archive :(
I'll try to workaround this for now by trying to work with the JAR directly or try to merge the two folders
Christian Beikov
@beikov
not sure if the "moduleness" could make a difference here though
newk5
@newk5
hello everyone, is there an SPI which would allow me to override the default serialization logic in weld?
I'd like to experiment swaping out the built-in java serialization that weld uses with kryo which uses a faster/lighter implementation
is such a thing possible without modifying weld internals (maybe with an SPI)?
Matej Novotny
@manovotn

Hello @newk5,

that's not possible. A quick look at what kryo does shows me that it would have to be adapted on the framework level (WildFly or any other fwk using Weld) as well which isn't the case.

newk5
@newk5
I see, thanks for the quick reply
Денис Бабоченко
@stasmihailov
Hello everyone! I have a question: is it possible to trigger weld injection programmatically, i.e. without using annotations, but e.g. from just the interface name?
Use case: i have a custom wildfly subsystem, which would have to inject a bean from a deployed application during the INSTALL phase of wildfly (suppose ive already resolved all the classloading issues). WIldfly subsystems are loaded by ServiceLoader
Matej Novotny
@manovotn

Hi @stasmihailov

is it possible to trigger weld injection programmatically, i.e. without using annotations, but e.g. from just the interface name?

If what you mean is injection into an object that is not CDI-managed, than no, you cannot do that based on interface. You are probably talking about a scenario which is somewhat similar to Unmanaged, read up on that to see if it can help you. But it won't work on interfaces and without annotations anyway.

Spec link (albeit spec is very bare bones in this) - https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#bm_obtain_unmanaged_instance

i have a custom wildfly subsystem, which would have to inject a bean from a deployed application during the INSTALL phase of wildfly

So you are basically trying to inject a bean into deployment phase (into a processor maybe?) of certain application? You could try to programmatically resolve the bean via CDI.current().getBeanManager().createInstance().select(...). But I suspect WFLY won't let you because of class loaders (CDI.current() is caller sensitive in this case) and CDI container is not considered to be running for that given app while it is deploying.

My actual goal is to somehow load a deployment bean into a custom subsystem, before the application is deployed from the client's standpoint (i.e. before undertow starts serving requests). It doesnt have to exactly occur at deployment phase though. But now, Im not sure if its even possible to access a bean from a subsystem at all, even after deployment, e.g. in runtime
Matej Novotny
@manovotn
WFLY custom extensions (which, I think, is what you describe) are not a standard bean archive and as such won't create beans that would be accessible for other deployments. This is because, per se, they are not standard deployments (and since they are in theory available to all deployment, you wouldn't want their bean states shared).
You could perhaps bypass that by registering said beans with CDI extension. I.e. place a CDI extension in the custom WFLY extension. CDI extensions can register beans for instance via AfterTypeDiscovery event where you can register an AnnotatedType.
@stasmihailov ^
Денис Бабоченко
@stasmihailov
Hmm, I’ll try that, thanks! But to be specific, the bean is in the deployment, and im trying to access that bean from an unmanaged code in the custom extension. So the CDI.current() seems like a solution for now, but i would also have to figure out the correct lifecycle phase
Björn Kautler
@Vampire

When I start my application using gradlew run all works fine.
But if I package up the final distribution with shipped JRE and so on and then try to start it, I get

 java.lang.IllegalStateException: WELD-ENV-000033: Invalid bean archive scanning result - found multiple results with the same reference: /app/build/image/my-app-linux/lib/txw2-2.3.1.jar
        at org.jboss.weld.environment.deployment.discovery.AbstractDiscoveryStrategy.performDiscovery(AbstractDiscoveryStrategy.java:116) ~[weld-environment-common-3.1.8.Final.jar:3.1.8.Final]
        at org.jboss.weld.environment.se.Weld.createDeployment(Weld.java:966) ~[weld-se-core-3.1.8.Final.jar:3.1.8.Final]
        at org.jboss.weld.environment.se.Weld.initialize(Weld.java:787) ~[weld-se-core-3.1.8.Final.jar:3.1.8.Final]
        at org.jboss.weld.environment.se.Weld.initialize(Weld.java:176) ~[weld-se-core-3.1.8.Final.jar:3.1.8.Final]
        ...

Any idea what might got wrong here or any hint how to interpret this error?

And it also varies.
On Heroku I get that one, locally it is about jaxb-api-2.3.1.jar
Björn Kautler
@Vampire
Hm, I started with SeContainerInitializer.newInstance().addProperty("javax.enterprise.inject.scan.implicit", TRUE).initialize();,
because adding a beans.xml only works when the code is run from a JAR, so a usual gradlew run would for example not find the beans as resources and classes are in different folders which are added to the classpath.
If I instead start with SeContainerInitializer.newInstance().addPackages(true, MyApplication.class).initialize();,
it seems to work better.
But I still wonder why the libs are scanned twice with that property.
Björn Kautler
@Vampire
Ah, found it. jaxb-runtime has a Class-Path entry where 6 libs are referenced, among them jaxb-api and txw2.
The ClassPathBeanArchiveScanner adds those files.
And when run through gradlew run, the files are taken directly from Gradle cache, so the relative reference does not work and the files are not added.
Björn Kautler
@Vampire
Oh, it was me contributing the manifest entry scanning in weld/core#1924.
But I thought I cared for not producing duplicate entries. :-/
Björn Kautler
@Vampire
I opened a PR that fixes it (weld/core#2565) and finally also one to fix WELD-2605 (https://github.com/weld/core/pull/2564).
I got you right @manovotn, that it is sufficient to have the PR against 3.1 and you will pick it to 4.0 and master, correct?
Björn Kautler
@Vampire
And is there a way to set bean discovery mode of the synthetic bean archive to "annotated"?
Now that I switched from SeContainerInitializer.newInstance().addProperty("javax.enterprise.inject.scan.implicit", TRUE).initialize();
to SeContainerInitializer.newInstance().addPackages(true, MyApplication.class).initialize();, I suddenly get a
WELD-001125: Illegal bean type javax.enterprise.util.TypeLiteral<...> ignored on [EnhancedAnnotatedTypeImpl] private static class ...
that I didn't get before and that is because a class is interpreted as bean that is not intended to be a bean as far as I got it.