Re: [weld-dev] How to use Weld servlet Env with Grizzly?
by Alex Sviridov
Hi all,
I found out that in order to control instance creating in Grizzly it is necessary
to override some methods in WebappContext. So I created these two classes:
https://github.com/PavelKastornyy/weld-core/tree/master/environments/serv...
However, objects are not injected in servlets as expected. Could anyone of Weld developers comment my code?
Best regards, Alex
>Понедельник, 21 мая 2018, 17:49 +03:00 от Martin Kouba <mkouba(a)redhat.com>:
>
>Dne 21.5.2018 v 16:44 Alex Sviridov napsal(a):
>> Hi Martin,
>>
>> Thank you for your answer. I implemented half of container -
>> https://github.com/PashaTurok/core/blob/master/environments/servlet/core/...
>>
>> and changed WeldServletLifecycle
>> https://github.com/PashaTurok/core/blob/20398c204f4e24d2a6f1c1ea3bc1d9381...
>>
>>
>> To use my Context I do:
>> WebappContext webContext = new WebappContext("WebappContext", "");
>> Listener listener = new Listener();
>> webContext.addListener(listener);
>> webContext.deploy(server);
>>
>> to add some servlet/filter to Grizzly WITHOUT CDI I do :
>> ServletRegistration registration =
>> webContext.addServlet("ServletContainer", (Class<Servlet>)
>> Class.forName("org.temp.TestServlet"));
>> registration.addMapping("/");
>>
>> I've looked through undertow WeldServletExtension but can't understand
>> when and where this extension is called.
>
>In undertow an extension is a service provider of
>io.undertow.servlet.ServletExtension, loaded automatically during
>startup (see also java.util.ServiceLoader). You need to find out how and
>where Grizzly allows to customize the instantiation/injection of
>components.
>
>> As I understand I need to make Grizzly webContext use CDI, so I need to
>> make some factory for every
>> servlet/filter/listener that will create instances of them using
>> BeanManager and make Grizzly to use
>> these factories. But where is the point where these factories will be
>> used? Could you show me the direction?
>>
>> Best regards, Alex
>>
>> Понедельник, 21 мая 2018, 15:23 +03:00 от Martin Kouba
>> < mkouba(a)redhat.com >:
>>
>> Hi Alex,
>>
>> do you have some publicly available project so that we can discuss a
>> real code?
>>
>> In general, if you want to integrate Weld servlet with a custom servlet
>> container:
>>
>> 1. Implement org.jboss.weld.environment.servlet.Container, e.g.
>> GrizzlyContainer
>> - Container#touch() should return true if a specific container is
>> detected
>> - Container#initialize() and Container#destroy() can be used to
>> init/cleanup the container
>> - note that ContainerContext#getManager() returns a BeanManager
>> which
>> could be used later, e.g. for dependency injection; you can also obtain
>> a BeanManager from the servlet context - see for example [1]
>>
>> 2. Implement a container specific "injection support"
>> - each servlet container should provide its own SPI - you should
>> implement this SPI so that injection into servlets, listeners and
>> filters is supported; see for example [2] how undertow support is
>> implemented
>>
>> 3. There is no need to "connect" EnhancedListener in any way. It should
>> be registeded automatically. However, if you're trying to run an
>> embedded servlet container you will need to register
>> org.jboss.weld.environment.servlet.Listener manually.
>>
>> Martin
>>
>>
>> [1]
>> https://github.com/weld/core/blob/master/environments/servlet/core/src/ma...
>>
>> [2]
>> https://github.com/weld/core/blob/master/environments/servlet/core/src/ma...
>>
>> Dne 18.5.2018 v 19:52 Alex Sviridov napsal(a):
>> > Hi all
>> >
>> > Could anyone explain how to connect WebappContext that implements
>> > ServletContext, to
>> > Weld servlet env? I've read the code, but still can't understand
>> how to
>> > connect SomeContainer,
>> > that implements servlet.Container, EnhancedListener and Grizzly
>> > WebappContext? Could anyone
>> > describe main principles how to do it? I would be very thankful.
>> >
>> > --
>> > Best regards, Alex Sviridov
>> >
>> >
>> > _______________________________________________
>> > weld-dev mailing list
>> > weld-dev(a)lists.jboss.org <mailto:weld-dev@lists.jboss.org>
>> > https://lists.jboss.org/mailman/listinfo/weld-dev
>> >
>>
>> --
>> Martin Kouba
>> Senior Software Engineer
>> Red Hat, Czech Republic
>>
>>
>>
>> --
>> Alex Sviridov
>
>--
>Martin Kouba
>Senior Software Engineer
>Red Hat, Czech Republic
--
Alex Sviridov
6 years, 6 months
How to use Weld servlet Env with Grizzly?
by Alex Sviridov
Hi all
Could anyone explain how to connect WebappContext that implements ServletContext, to
Weld servlet env? I've read the code, but still can't understand how to connect SomeContainer,
that implements servlet.Container, EnhancedListener and Grizzly WebappContext? Could anyone
describe main principles how to do it? I would be very thankful.
--
Best regards, Alex Sviridov
6 years, 6 months
Weld SE as JPSM auto module (report)
by Alex Sviridov
Hi all,
I am posting the result of solution to make Weld work as JPMS auto module.
In this solution I use only module path. I manually create JPMS layer and add all modules
to it. For Weld I added the following modules:
<module file="cdi-api-2.0.jar"/>
<module file="javax.annotation-api-1.3.2.jar"/>
<module file="javax.inject-1.jar"/>
<module file="javax.interceptor-api-1.2.jar"/>
<module file="jboss-classfilewriter-1.2.2.Final.jar"/>
<module file="jboss-logging-3.2.1.Final.jar"/>
<module file="guava-18.0.jar"/>
<module file="weld-se-core-3.0.4.Final.jar"/>
<module file="weld-environment-common-3.0.4.Final.jar"/>
<module file="weld-core-impl-3.0.4.Final.jar"/>
<module file="weld-spi-3.0.SP3.jar"/>
<module file="weld-api-3.0.SP3.jar"/>
<module file="jandex-2.0.5.Final.jar"/>
Note, that jandex is 2.0.5 but not 2.0.3 as 2.0.3 doesn't work well with java9. Besides Weld modules
I have two modules - in beanModule( here I have my cdi beans + beans.xml) and serverModule (here
I create Weld etc).
In serverModule I have the following code:
Weld builder = new Weld()
.property("org.jboss.weld.construction.relaxed", true)
.setClassLoader(this.getClass().getClassLoader())
.setResourceLoader(new ResourceLoaderImpl());
WeldContainer container = builder.initialize();
BeanManager bm = container.getBeanManager();
This is my ResourceLoaderImpl:
public class ResourceLoaderImpl implements ResourceLoader {
private static final String ERROR_LOADING_CLASS = "Error loading class ";
@Override
public Class<?> classForName(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
throw new ResourceLoadingException(ERROR_LOADING_CLASS + name, e);
} catch (LinkageError e) {
throw new ResourceLoadingException(ERROR_LOADING_CLASS + name, e);
} catch (TypeNotPresentException e) {
throw new ResourceLoadingException(ERROR_LOADING_CLASS + name, e);
}
}
@Override
public URL getResource(String name) {
try {
Module module = this.getClass().getModule().getLayer().findModule("beanModule").orElse(null);
ModuleReference reference = getReference(module);
Optional<URI> uri = reference.open().find(name);
if (uri.isPresent()) {
return uri.get().toURL();
} else {
return null;
}
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
@Override
public Collection<URL> getResources(String name) {
List<URL> result = new ArrayList<>();
//HERE WE NEED MODULE ITERATION
URL url = this.getResource(name);
if (url != null) {
result.add(url);
}
return result;
}
@Override
public void cleanup() { }
}
In beanModule in module-info I open packages, that contains beans.
The solution WORKS, via BeanManager I can get whatever bean I need. The only problem is that I can't
understand what I should return in getResouce(String) if I have many modules - what module first I should
return? For example, when weld calls getResource("META-INF/beans.xml") - ?
It would be very interesting to to get some comments.
--
Best regards, Alex
6 years, 6 months
Staring weld container for SE environment makes me load java ee classes.
by Alex Sviridov
Hi all
I am trying to start weld container (2.3.5) as auto module in JPMS. This is my code
Deployment deployment = new Deployment() {
@Override
public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() {
List<BeanDeploymentArchive> list = new ArrayList<>();
list.add(archive);
return list;
}
@Override
public BeanDeploymentArchive loadBeanDeploymentArchive(Class<?> beanClass) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public ServiceRegistry getServices() {
SimpleServiceRegistry simpleServiceRegistry = new SimpleServiceRegistry();
simpleServiceRegistry.add(ResourceLoader.class, new ResourceLoaderImpl());
return simpleServiceRegistry;
}
@Override
public Iterable getExtensions() {
return new ArrayList<>();
}
};
bootstrap.startContainer(Environments.SE, deployment);
The problem is that in BeanDeployment constructor all services are loaded here https://github.com/weld/core/blob/d0019511ea776e9c35eab68c4d493c2df882a12... and if I in my resource loader service return instead of all java-ee classes null, I get null pointer exception, for example here https://github.com/weld/core/blob/d0019511ea776e9c35eab68c4d493c2df882a12...
I can't understand why all these classes are requested from me, as I am in SE. Or I am doing something wrong. Could anyone help me?
--
Best regards, Alex Sviridov
6 years, 6 months
Weld and JPMS
by Alex Sviridov
Hi all
Half a year has passed since Java 9 release. Can anyone say if there are any documentation,
solutions etc how to work with JPMS in Weld?
--
Alex Sviridov
6 years, 6 months
@WithAnnotations filtering not picking up annotations from implemented interfaces
by Marko Bekhta
Hi all,
In Hibernate Validator CDI extension we are using @WithAnnotations to filter
beans that potentially need to be validated (for actual usage see [1]):
public <T> void processAnnotatedType(@Observes @WithAnnotations({
Constraint.class,
Valid.class,
ValidateOnExecution.class
}) ProcessAnnotatedType<T> processAnnotatedTypeEvent) {
// doing something ...
}
The problem that we've stumbled upon is that it looks like this filtering
does
not take into account the information from implemented interfaces. For
example
let's assume we have an interface:
@ValidateOnExecution(type = ExecutableType.ALL)
public interface ShipmentService {
public void findShipment(@NotNull String id);
}
which is implemented by ShipmentServiceImpl:
public class ShipmentServiceImpl implements ShipmentService {
@Override
public void findShipment(String id) {
}
}
Our expectation would be that as interface is marked with one of the
annotations
listed among values of @WithAnnotations filter, the corresponding bean
(ShipmentServiceImpl) would be pushed to processAnnotatedType(..) method.
But it
is not. As a result we don't create a validation proxy and corresponding
service
bean never performs any validation operations. In case when any of the
filtered
annotations is added to the impl bean things start to work (impl bean is
processed).
The above case shows placement of annotation on a type level, but similar
behavior is observed in cases when annotation is on a method level.
As forcing presence of one of the annotations from the filter list on a impl
beans is not really an option, an alternative could be to drop the
@WithAnnotations filtering completely. Which is also not that great, as
dropping the filtering would mean that:
- Validation extension would need to process all possible beans that are
available
- Such processing requires calls to Hibernate Validatior which must create
the metadata
for each bean hierarchy and store it, even if nobody actually needs to
validate those
beans.
- This would lead to much greater memory consumption as well as longer
bootstrap
time. Which is not good.
Hence we would like to ask if there is any particular reasons why
@WithAnnotations
filter does not consider looking at super classes and implemented
interfaces to check
for annotations listed in @WithAnnotations?
Have a nice day,
Marko
[1]
https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main...
6 years, 7 months