Is it possible to set up Jetty with CDI for websockets? - websocket

I have managed to get weld CDI to work with jetty embedded for both servlets and rest. My question is: Is it possible to get CDI to work with WebSockets (JSR-356)?

CDI with javax.websocket is not well defined in the official JSR-356 spec, and wiring it up has proven sufficiently odd that each implementation is doing it differently, with different levels of support.
(This is likely because the JSR-356 spec was written to be intentionally unconnected to Java EE and Servlet in general, allowing it to exist in non Java EE environments)
There are a few open issues with it at the Jetty side.
423647 - New Extensions should be created via ServletContextHandler.createInstance(Class)
423645 - New ClientEndpointConfig.Configurators should be created via ServletContextHandler.createInstance(Class)
423367 - New ServerApplicationConfig objects should be created via ServletContextHandler.createInstance(Class)
423365 - New ServerEndpointConfig.Configurators should be created via ServletContextHandler.createInstance(Class)
423364 - New Encoders should be created via ServletContextHandler.createInstance(Class)
423363 - New Decoders should be created via ServletContextHandler.createInstance(Class)
423336 - New Endpoints should be created via ServletContextHandler.createInstance(Class)
I'm one of the maintainers of the websocket impl at Jetty, and would love to have someone help test the CDI integration (none of the Jetty developers themselves use CDI so its hard to get good, real-world, test cases to work against)

Related

Is it possible to access the spring context outside of a spring-boot application?

I am trying to create a standalone database application which can offer CRUD operations to other applications/modules...
I am aware of the need to create the entities and services used by the application in another artifact since you cannot depend on a spring-boot application alone.
But, can one get the runtime spring-configuration of a spring-boot application? So one can access a service that is deployed on my application?
For best through-put I am looking for a way to use services on a running spring-boot database application on the same JVM in order to minimise overhead...
RMI
What you want is technically it is possible using basic Java RMI (remote method invocation), you just register the bean as the implementation instance and share the interface between the two JVMs, either on localhost or even on different machines.
Spring even gives some additional support for this using RmiProxyFactoryBean, see Spring Remoting RMI article.
From above article, you can export it, using:
#Bean
RmiServiceExporter exporter(CabBookingService implementation) {
Class<CabBookingService> serviceInterface = CabBookingService.class;
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setServiceInterface(serviceInterface);
exporter.setService(implementation);
exporter.setServiceName(serviceInterface.getSimpleName());
exporter.setRegistryPort(1099);
return exporter;
}
and import it, using:
#Bean
RmiProxyFactoryBean service() {
RmiProxyFactoryBean rmiProxyFactory = new RmiProxyFactoryBean();
rmiProxyFactory.setServiceUrl("rmi://localhost:1099/CabBookingService");
rmiProxyFactory.setServiceInterface(CabBookingService.class);
return rmiProxyFactory;
}
Then you can use it in your application context based on your interface.
However I would not suggest to share beans like this because it has the same problem RMI has.
Shared library
Another way to do what you want is to create a shared library that can be included in other projects.
If all the project, which want to use it are Spring Boot application you can create a Spring Boot starter, see Spring documentation.
This way, other applications just have to add the dependency and they already has access to the beans in their application context, as well as the shared domain objects.
If other application use just regular Spring, they can just #Import your main configuration class.
If other apps are using Java, but not Spring, you can still use Spring inside, just provide a factory, which creates an internal Spring context.
REST service
If other applications are not written in Java, your best bet is to expose a REST interface for them to use the database applications.

Using SpringBoot as an application loader

I have a spring-boot app that acts as a small framework for other apps. It provides a couple of JMS queues and a DAO layer to retrieve and store data from a common set of data stores. The problem is that the original developer of this framework app is scanning all the package "com.mycompany" (rather than com.mycompany.framework) so that it can load the beans of the specific app that may be declared under com.mycompany.myapp1 or com.mycompany.myapp2 an which JARs are bundled together with the JARs of the framework.
We only load a single app in the JVM (app1 or app2), but these apps may share other libraries and sometimes we end up with beans in the context that we don't need. (these may be needed in app1 but not in app2)
So, what would be your advice ?
My problem is similar to what was described here:
https://github.com/spring-projects/spring-boot/issues/3300
I am debating if each app should be aware of the framework and load it. Or if the framework should instantiate a class loader and create a new Spring context loading the app specific code as suggested in the link above.
Perhaps you should consider leveraging some of Spring Boot's Auto Configuration capabilities such as #ConditionalOnProperty or #ConditionalOnClass in your framework. That way, you can only actually enable certain beans if and when the application using your framework takes some specific action (e.g. has a given jar on the classpath, or sets a configuration value). For reference check out: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-developing-auto-configuration

WebSphere 8 : JAX-WS client for Axis2 WS

I am trying to write a JAX WS client for a service exposed using Axis2, WebSphere8, Java 1.6.
Standalone client(i.e. client running in my local machine) works fine but when I deploy the client in a application running in same websphere server I get
java.lang.ClassCastException: Cannot cast class org.apache.axis2.jaxws.spi.Provider to class javax.xml.ws.spi.Provider
at line OpenPortType service = OpenService
.create(wsdlFile.toURL(),
new QName( "http://www.test.com/schemas/public/open-api/Open/","OpenService")).getPort(
OpenPortType.class);
When I tried to google I found similar problem existed in weblogic : https://wso2.org/jira/browse/CARBON-4835
When we see source of axis2.jaxws.spi.Provider class we come to know that it's a subclass of javax.xml.ws.spi.Provider !!
I'm wondering what could be wrong ? Any idea ?
Unless you are calling Axis2 capabilities directly, rather than simply using JAX-WS APIs, you do not want to package Axis into your EAR. WebSphere does provide its own JAX-WS implementation which I'm not surprised conflicts with another JAX-WS implementation you've deployed in your app. (In particular, note that WebSphere's own implementation is based on Axis2.)
If you do need to deploy a different implementation, you'll probably have to at least adjust your WebSphere classloader policy to parent_last. There might be more to do as well; it's been a while since we did this ourselves. But it's much easier and cleaner to use the built-in JAX-WS implementation, which means not deploying any of those jars at all.

Spring transaction support in Netty handlers

I am using the following versions:
Spring 3.1.1.RELEASE
Netty 3.4.0.Final
Hibernate 3.5.6-Final
Now, I have a Netty server that works fairly well - the root of the server, the pipeline factories and the base "stub" of the server that owns everything are all set up with Spring. In this stub, spring #Transactional annotations work just fine.
However, in the handlers, which are stateful and created dynamically depending on what state the user is in - #Transactional doesn't work. I'm fairly sure I understand why. I even have a "solution" - but it's not very good.
After the decoders and encoders, I add an ExecutionHandler:
pipeline.addLast("execution", new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(16,1000000, 1000000)));
This appears to be where the Spring transaction support is breaking. Since Spring is unaware of these threads, it can't bind any transactions to them. The classes are proxied correctly, but in debug they have no associated transactions.
My solution is crappy, and it needs to be replaced by a real solution:
Session sess = SessionFactoryUtils.getSession(getSessionFactory(), true);
That's bad because it relies on me to release the session, and it may not even be transactional, I haven't checked. It sucks in a lot of ways.
Anyway - the root of the question. Given the above tech, what's my path to getting my #Transactional notations working on the Netty handlers?
Write an ExecutionHandler that's Spring aware?
NOTE: I can't upgrade to Hibernate 4, due to lack of compatibility with Spring-Flex, used in another project in the group. Probably the same story for the Spring version, can't remember.
I suggest you create these netty's handler inside spring container and inject the service or persistence layer into the handlers so you can have these layers independence from netty and of course these are old school spring beans.

Spring 3.1 Environment Abstraction and EJB integration

I'm trying to use the new environment abstraction in our Java EE/EJB application. We're already using SpringBeanAutowiringInterceptor to inject Spring Beans into EJBs by using the standard beanRefContext.xml to bootstrap the shared application context for the Java EE app.
Now I've written a concrete Environment class (derived from Spring 3.1 AbstractEnvironment) which uses some kind of environment "auto" detection to select the correct active profile for the machine on which the app is running on. With this feature our app can be delivered with all properties for all environements (inside the ear) and auto select the correct property set.
The problem is now that org.springframework.beans.factory.access.SingletonBeanFactoryLocator.createDefinition(String, String) builds a bean factory group around the beans/context in beanRefContext.xml using the StandardEnvironment class, and I see no simple way to configure the environment implementation to use here without rewriting(overwriting) some part of SingletonBeanFactoryLocator.
Is there a simple solution for this, or is s.th. planned in the direction for supporting to specify the Environment implementation with the EJB/Java EE integration?

Resources