How to dynamically configure the WebLogicCluster property outside of web.xml - java

I have a web application deployed as war file in weblogic 10.3.3. Now I want to make this application clusterable. For this I'm using the HttpClusterServlet from Weblogic as a load balancer. According to the documentation I can put this servlet configuration into the web.xml
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>server-1:7122|server-1:7123</param-value>
</init-param>
</servlet>
The problem is that this configuration is hard wired at build time and can't be reconfigured at runtime. For instance I would like to be able to add 5 more servers dynamically. I had several ideas to solve that problem:
Extend the weblogic.servlet.proxy.HttpClusterServlet with an own servlet implentation. This is not possible, the class is final.
Use a servlet filter to reconfigure the servlet. The servlet is not accessible anymore through ServletContext().getServlet(String) since Java Servlet API 2.1, with no direct replacement.
Reflection might be an option, but I couldn't figure out a reliable way to access the configuration
All of my attempts to reconfigure this init-param externally failed so far. I'm open to any solutions.

This might help How to externalize web.xml servlet init-param? Spring DelegatingFilterProxy for Servlets? Even if your not using Spring it wouldn't be too hard to port that servlet to another IoC container.

Related

Vaadin 19/20 + official gradle plugin - custom servlet subpath to run within existing legacy web application along another Java framework

Environment
Spring 4.3 (no Spring Boot!), JDK 8/11, Tomcat 8.5.x, Vaadin 19/20-SNAPSHOT
I have a legacy webapp running another servlet-api-driven web framework at http://app.com. I want to add a path that adds a Vaadin-driven UI to this application - let's say at http://app.com/vaaadin-app . I'm using the newly developed official Gradle plugin. (Both Vaadin and non-Vaadin web applications should be run from single WAR, effectively sharing single classloader for shared state access, so no proxy/rewrite/etc solutions will help here).
Problem
After adding dependencies the Vaadin app is properly built and war created. Yet as soon as I call http://app.com (not http://app.com/vaadin-app) it looks like Vaadin servlet/whatever is taking over all requests. It looks like it is automatically initialized by (I guess) servlet 3.0 annotations.
Question
How can I enable Vaadin only for http://app.com/vaadin-app and keep it away from altering requests not directed there? I know with Vaadin 8 it was possible to achieve this with:
<servlet>
<servlet-name>vaadinServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>app.vaadin.additem.AddItemUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/vaadin-app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
In other words: how to prevent Vaadin 19/20 from spawning itself automatically for /* but to serve application only when user hits the /vaadin-app/* servlet path???
I think in case of maven plugin there was the "disable.automatic.servlet.registration" option to achieve this? But I don't see anything like this in case of Gradle plugin.
Thanks!
The servlet registration in Vaadin should have nothing related to Gradle, so applying the generic instructions should work. The automatic servlet registration is omitted if you define a VaadinServlet manually (extend it and map the servlet to your location of choice using #WebServlet).
Check this part of the documentation for more details: https://vaadin.com/docs/latest/flow/advanced/application-lifecycle/#automatic-servlet-registration

Configuring servlet url-patterns without web.xml

I know this can be done in servlet 3.0 with the #Webservlet annotation where you just assign the url-patterns and not have to do any configurations within a web.xml. Is there a way to programmatically assign a servlets url-pattern for applications running servlet 2.5?
I am creating a library which multiple applications will depend on and trying to make it so each of these applications do not have to explicitly configure any servlet url mappings for the servlets in the library I am creating within their respective web.xml file.
Thanks,
Since the web.xml and #Webservlet are both mechanisms for the server to know where to route requests by examining the war, you would have to be able to manipulate the server if you wanted to do it in code. This is at least theoretically possible, since the server could offer for example a JMX endpoint for configuration or you could go directly into the innards of the server.
However while it might be possible, it would be a non-standard way and you would have to write different tricks for all the servers you want to support. That's not something you want to do.
Finally, if you're creating a library, why does it have servlets in it? It shouldn't be the responsibility of the library to create servlets or decide which urls they're assigned to.

Is there a generic way to specify the context-root for a WebService?

I'm new to writing web services, and am struggling with understanding how to specify the context root.
I've got my class annotated with
#Service
#javax.jws.WebService(endpointInterface= "com.domain.clientservices.lendingsimulation.model.v1.LendingSimulationServicePortType", targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/V1.2", serviceName="LendingSimulationService", portName="LendingSimulationServicePort")
but I am not sure how to configure the context-root/path for it. I read that I could configure it as a servlet in web.xml, but that seems to be the case for a web service that is not annotate. Am I wrong? I have tried the following configuration in web.xml:
<servlet>
<description>This is the description for the LendingSimulation Service</description>
<display-name>Lending Simulation Service</display-name>
<servlet-name>LendingSimulationService</servlet-name>
<servlet-class>com.domain.clientservices.lendingsimulation.service.LendingSimulationServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LendingSimulationService</servlet-name>
<url-pattern>/WebService</url-pattern>
</servlet-mapping>
however, when I launch in JBoss, I get an error msg:
17:39:33,710 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/LendingSimulationService].[LendingSimulationService]] (http--127.0.0.1-8080-2) Allocate exception for servlet LendingSimulationService: java.lang.ClassCastException: com.domain.clientservices.lendingsimulation.service.LendingSimulationServiceImpl incompatible with javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1156) [jbossweb-7.0.1.Final.jar:7.0.2.Final]
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:952) [jbossweb-7.0.1.Final.jar:7.0.2.Final]
... (omitted for brevity)
I've read that I can configure jboss-web.xml specifically, but I assume there is a more generic way of doing this that can be applied to all app servers - isn't there? Or must I configure the service independently, depending on the AS that I am deploying to (ie: one way for Tomcat, one way for GlassFish, one way for JBoss, one way for WebSphere, etc...).
Is there an annotation I can use to specify my path for the web-service? Or a config param in the web.xml file?
Thanks!
Eric
Turns out that the JBoss error I was getting was due to the webservices module not being enabled. In JBoss7.0/7.1, you need to run the standalone-preview.xml config to get webservices for an out-of-box download: ie: standalone.sh --server-config=standalone-preview.xml. That eliminated the ClassCast/Servlet exception. However my question still remains if there is not a better/other way to accomplish this (perhaps via annotations) than declaring it as a servlet in web.xml.

How can I list all deployed jax-ws webservices?

I have deployed some jax-ws webservices in a tomcat:
web.xml:
...
<servlet>
<servlet-name>WebServiceJaxWs</servlet-name>
<servlet-class>...a bean of mine which overwrites WSServletDelegate</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
...
The webservices themselves are defined in the sun-jaxws.xml
They work just fine.
I now need to write a jsp, which displays all deployed webservices. I have access to the servlet context, but I simple cannot find a way to access the WebServiceJaxWs Servlet. My idea was to access it and then enumerate the published endpoints.
Any ideas?
The manual way I can think of is to parse your sun-jaxws.xml and get the information from there.
Maybe you could deploy all those web services as JMX beans and see them using JConsole.

Configuring velocity within a tomcat web application. (Cookbook wanted)

I have recently been introduced to the Velocity project.
I have written a template and have run it as a simple Java application.
Integration within my existing web project has not been that easy.
Can anyone supply a cookbook for integrating Velocity and Tomcat?
Thanks all!
Tomcat is a servlet container; you don't need to integrate Velocity with it but rather with your application. How exactly that should be done depends on your application:
If you're using Spring, it has VelocityViewResolver available along with instructions on how to set it up.
If you're using straight servlets / JSP take a look at VelocityViewServlet
Other frameworks (Struts / etc...) may or may not have built-in Velocity integration; take a look at this page (bottom section) for more details.
The straightforward way is to define a VelocityViewServlet in web.xml
<servlet>
<servlet-name>view</servlet-name>
<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
<init-param>
<param-name>org.apache.velocity.properties</param-name>
<param-value>/WEB-INF/velocity.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>view</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
In velocity.properties
#resource loaders
resource.loader = production
production.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
Then put your template at the root of your webapp and access it from the web browser using its name as the URL. e.g.
http://localhost:8080/index.vm

Categories