web.xml required in Spring applications - java

A Spring web application is just a normal web application using servlet API 3.0.
In servlet API 3.0 web.xml file is optional (most of the time).
I' ve tried not to include web.xml inside my Spring aplication,but somehow it seems to be required even using Servlet 3.0
The only difference between a Spring applications and web apps I've run successfully without writing a web.xml file, is that in Spring filters and servlets are defined inside jars in the lib folder.
Any clues why this happens ?

You can't just exclude the web.xml, as you (at least) need to define which version of the Servlet API are you using.
At the minimum, you'd need this in your web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
Everything else (servlets, filters, etc.) can be configured with annotations.

Fortunately, you can create completely XML free Spring applications nowadays.
There are various different options for such configs with or without Spring Boot.
With pure Spring you can use AbstractAnnotationConfigDispatcherServletInitializer
With Spring Boot, you can have SpringBootServletInitializer.
This is my Github repository with bunch of projects based on both approaches.
Version of servlets is defined by Servlet API you have on your classpath. E.g.:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>
or
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
You also don't specify servlets, as Spring has own implementation of servlet DispatcherServlet.
Filters are registered as beans into Spring context.

Related

JasperException while using JSTL [duplicate]

I don't know what I've done incorrectly, but I can't include JSTL. I have jstl-1.2.jar, but unfortunately I get exception:
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:116)
at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:315)
at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:148)
at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:429)
at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:492)
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1439)
at org.apache.jasper.compiler.Parser.parse(Parser.java:137)
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:255)
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:170)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:332)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
I have:
pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
index.jsp
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<head></head>
<body></body>
</html>
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
That URI is for JSTL 1.0, but you're actually using JSTL 1.2 which uses URIs with an additional /jsp path (because JSTL, who invented EL expressions, was since version 1.1 integrated as part of JSP 2.0 (released way back in 2001!) in order to share/reuse the EL logic in plain JSP too).
So, fix the taglib URI accordingly based on JSTL 1.2 documentation:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Further you need to make absolutely sure that you do not throw multiple different versioned JSTL JAR files together into the runtime classpath. This is a pretty common mistake among Tomcat users. The problem with Tomcat is that it does not offer JSTL out the box and thus you have to manually install it. This is not necessary in normal Jakarta EE servers. See also What exactly is Java EE?
In your specific case, your pom.xml basically tells you that you have jstl-1.2.jar and standard-1.1.2.jar together. This is wrong. You're basically mixing JSTL 1.2 API+impl from Oracle with JSTL 1.1 impl from Apache. You should stick to only one JSTL implementation and the API version must match the impl version.
Installing JSTL on Tomcat 10.1.x
In case you're already on Tomcat 10.1.x (the second Jakartified version, with jakarta.* package instead of javax.* package, but the first version with the updated jakarta.tags.* namespace URNs instead of http://java.sun.com/jsp/jstl/* namespace URLs), use JSTL 3.0 via this sole dependency using the default Maven scope of compile (because Tomcat doesn't provide it out the box!):
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>
Note that the API dependency is already transitively included via this impl dependency, so you do not need to explicitly declare it.
Non-Maven users can achieve the same by dropping the following two physical files in /WEB-INF/lib folder of the web application project (do absolutely not drop standard*.jar or any loose .tld files in there! remove them if necessary).
jakarta.servlet.jsp.jstl-3.0.1.jar (this is the JSTL 3.0.1 impl of EE4J)
jakarta.servlet.jsp.jstl-api-3.0.0.jar (this is the JSTL 3.0 API)
As said, the namespace URIs have been changed to become URNs instead of URLs. JSTL core is since JSTL version 3.0 available via an easier to remember namespace URI in URN format:
<%# taglib prefix="c" uri="jakarta.tags.core" %>
See also JSTL 3.0 documentation.
Installing JSTL on Tomcat 10.0.x
In case you're on Tomcat 10.0.x (the first Jakartified version, with jakarta.* package instead of javax.* package), use JSTL 2.0 via this sole dependency using the default Maven scope of compile (because Tomcat doesn't provide it out the box!):
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
Note that the API dependency is already transitively included via this impl dependency, so you do not need to explicitly declare it.
Non-Maven users can achieve the same by dropping the following two physical files in /WEB-INF/lib folder of the web application project (do absolutely not drop standard*.jar or any loose .tld files in there! remove them if necessary).
jakarta.servlet.jsp.jstl-2.0.0.jar (this is the JSTL 2.0 impl of EE4J)
jakarta.servlet.jsp.jstl-api-2.0.0.jar (this is the JSTL 2.0 API)
Installing JSTL on Tomcat 9-
In case you're not on Tomcat 10 yet, but still on Tomcat 9 or older, use JSTL 1.2 via this sole dependency (this is compatible with Tomcat 9 / 8 / 7 / 6 / 5 but not older) using the default Maven scope of compile (because Tomcat doesn't provide it out the box!):
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>1.2.6</version>
</dependency>
Note that the API dependency is already transitively included via this impl dependency, so you do not need to explicitly declare it.
Non-Maven users can achieve the same by dropping the following two physical files in /WEB-INF/lib folder of the web application project (do absolutely not drop standard*.jar or any loose .tld files in there! remove them if necessary).
jakarta.servlet.jsp.jstl-1.2.6.jar (this is the JSTL 1.2 impl of EE4J)
jakarta.servlet.jsp.jstl-api-1.2.7.jar (this is the JSTL 1.2 API)
Installing JSTL on normal JEE server
In case you're actually using a normal Jakarta EE server such as WildFly, Payara, TomEE, GlassFish, WebSphere, OpenLiberty, WebLogic, etc instead of a barebones servletcontainer such as Tomcat, Jetty, Undertow, etc, then you do not need to explicitly install JSTL at all. Normal Jakarta EE servers already provide JSTL out the box. In other words, you don't need to add JSTL to pom.xml nor to drop any JAR/TLD files in webapp. Solely the provided scoped Jakarta EE coordinate is sufficient:
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version><!-- 10.0.0, 9.1.0, 9.0.0, 8.0.0, etc depending on your server --></version>
<scope>provided</scope>
</dependency>
Make sure web.xml version is right
Further you should also make sure that your web.xml is declared conform at least Servlet 2.4 and thus not as Servlet 2.3 or older. Otherwise EL expressions inside JSTL tags would in turn fail to work. Pick the highest version matching your target container and make sure that you don't have a <!DOCTYPE> anywhere in your web.xml as that would otherwise still trigger Servlet 2.3 modus. Here's a Servlet 6.0 (Tomcat 10.1.x) compatible example:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<!-- Config here. -->
</web-app>
And here's a Servlet 5.0 (Tomcat 10.0.x) compatible example:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<!-- Config here. -->
</web-app>
And here's a Servlet 4.0 (Tomcat 9) compatible example:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- Config here. -->
</web-app>
See also:
JSTL core taglib documentation (for the right taglib URIs)
EL expressions not evaluated in JSP
How to configure pom.xml for Tomcat 10+ or Tomcat 9-
#BalusC is completely right, but If you still encounter this exception, it means that something you have done wrong. The most important information you will find is on the SO JSTL Tag Info page.
Basically this is a summary of what you need to do to deal with this exception.
Check the servlet version in web.xml: <web-app version="2.5">
Check if JSTL version is supported for this servlet version: Servlet version 2.5 uses JSTL 1.2 or Servlet version 2.4 uses JSTL 1.1
Your servlet container must have the appropriate library, or you must include it manually in your application. For example: JSTL 1.2 requires jstl-1.2.jar
What to do with Tomcat 5 or 6:
You need to include appropriate jar(s) into your WEB-INF/lib directory (it will work only for your application) or to the tomcat/lib (will work globally for all applications).
The last thing is a taglib in your jsp files. For JSTL 1.2 correct one is this:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
I found another reason for this type of error: in my case, someone set the conf/catalina.properties setting tomcat.util.scan.StandardJarScanFilter.jarsToSkip property to * to avoid log warning messages, thereby skipping the necessary scan by Tomcat. Changing this back to the Tomcat default and adding an appropriate list of jars to skip (not including jstl-1.2 or spring-webmvc) solved the problem.
Download jstl-1.2.jar
Add this directive to your page: <%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Paste the JAR file in your WEB-INF/lib folder. This should work. (It
worked for me.)
jstl-1.2.jar --> <%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
jstl-1.1.jar --> <%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
also please check for the dependency jars that you have added javax.servlet.jar and javax.servlet.jsp.jstl-1.2.1.jar or not in your WEB-INF/lib folder. In my case these two solved the issue.
Add the jstl-1.2.jar into the tomcat/lib folder.
With this, your dependency error will be fixed again.
I just wanted to add the fix I found for this issue. I'm not sure why this worked. I had the correct version of jstl (1.2) and also the correct version of servlet-api (2.5)
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
I also had the correct address in my page as suggested in this thread, which is
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
What fixed this issue for me was removing the scope tag from my xml file in the pom for my jstl 1.2 dependency. Again not sure why that fixed it but just in case someone is doing the spring with JPA and Hibernate tutorial on pluralsight and has their pom setup this way, try removing the scope tag and see if that fixes it. Like I said it worked for me.
An answer for the year 2021
The question is still very popular, but all the answers are seriously outdated. All Java EE components were split off into various Jakarta projects and JSTL is no different. So here are the correct Maven dependencies as of today:
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>1.2.6</version>
</dependency>
Yes, the versions and groupIds do not match, but that's a quirk of the project's current state.
The most possible solutions for 2022
1 - Missing Libarires: download the library jstl/1.2 and Java Servlet API ยป 4.0.1
2 - Add these libraries to your project and also into the tomcat/lib folder.
3 - Add: <%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> first line of the page.
4 - if you are using maven add the following into pom.xml file :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
I have mentioned that the Maven dependency in the pom.xml is wrong. It should be
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
Just had similar problem in Eclipse
fixed with:
rightclick on project->Properties->Deployment Assembly->add Maven Dependencies
something kicked it out before,
while I was editing my pom.xml
I had all needed jar files, taglib uri and web.xml was ok
I had disabled MAVEN and Spring tools completely. And I had to add the following jar's for making my environment work right.
spring-aop-4.0.3.RELEASE.jar
spring-beans-4.0.3.RELEASE.jar (tough to find this fix, other org.springframework<3.versions> just did not work.
spring-context-4.0.3.RELEASE.jar
spring-core-4.0.3.RELEASE.jar
spring-expression-4.0.3.RELEASE.jar
spring-web-4.0.3.RELEASE.jar
spring-webmvc-4.0.3.RELEASE.jar
jstl-1.2.jar
The worst of all was jstl-api-1.2.jar and javax-servlet.jsp.jst-api-1.2.1.jar. They just did not work.
jstl-1.2.jar worked well.
If you use Spring boot, consider to remove server.tomcat.additional-tld-skip-patterns=*.jar from Application.properties if there is any
All of the answers in this question helped me but I thought I'd add some additional information for posterity.
It turned out that I had a test dependency on gwt-test-utils which brought in the gwt-dev package. Unfortunately gwt-dev contains a full copy of Jetty, JSP, JSTL, etc. which was ahead of the proper packages on the classpath. So even though I had proper dependencies on the JSTL 1.2 it would loading the 1.0 version internal to gwt-dev. Grumble.
The solution for me was to not run with test scope so I don't pick up the gwt-test-utils package at runtime. Removing the gwt-dev package from the classpath in some other manner would also have fixed the problem.
If using Tomcat 10:
Download
jakarta.servlet.jsp.jstl-2.0.0.jar
jakarta.servlet.jsp.jstl-api-2.0.0.jar
Place in /WEB-INF/lib folder.
Don't forget to restart Tomcat!
This workedfor me
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
I had the same issue , I am using eclipse, just in case others experience the same issue:
In eclipse double click the tomcat server,
stop the server
untick the "server modules without publishing"
start the server.
Resolved same problem in Netbeans 12.3 and Tomcat 9.0:
1.Write in pom.xml:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId><version>1.2</version>
</dependency>
2.Add jstl-1.2.jar in project.
3.Install manually artifact(Choose jstl-1.2.jar - downloaded from the Internet )
2023 version
Nothing else worked for me except adding the below to pom.xml:
PS: I do realize that version 2.0.0 of jakarta.servlet.jsp.jstl contains some vulnerability, please use caution.
<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
Resolved similar problem in IBM RAD 7.5 by selecting:
Projects properties
Project Facets
JSTL check-box

Glassfish 4.1: war inside ear does not expose webservices

I am currently working on upgrading an application from Java7 running on Glassfish 3.1.2.2, to Java8 running on Glassfish 4.1. The application is packaged as an ear-file, containing an ejb-jar, and a war. The war in turn contains some webservices.
In Glassfish 3.1.2.2, deploying the ear will lead to the war exposing a number of webservices. But, when I deploy the ear in Glassfish 4.1, no webservice are exposed. When listing the components for the ear in Glassfish, the war does not list webservices (only web) in 4.1 (but does in 3.1.2.2).
I have tried deploying the war-file as a standalone application, and when doing this the webservices becomes available.
Does anyone know if there is a known bug with regards to deploying webservices through an ear-file with Glassfish 4.1?
When it comes to changes, I have upgraded some dependencies, but as far as I know there is nothing that should affect this.
My application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
"http://java.sun.com/dtd/application_1_3.dtd">
<application>
<display-name>myApplication-ear</display-name>
<description>myApplication</description>
<module>
<ejb>myApplication-ejb-5.2-SNAPSHOT.jar</ejb>
</module>
<module>
<web>
<web-uri>myApplication-war-5.2-SNAPSHOT.war</web-uri>
<context-root>/myApplication-war</context-root>
</web>
</module>
</application>
The problem was an old dependency:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.7</version>
</dependency>
I removed it because it is already included in rt.jar in the java installation.
Somehow Glassfish didn't handle this at all, the webservices simply didn't work and no traces of error in the server.log
Can this be your scenario (?): EJB module deployment may fail when an EJB that is exposed as a web service, and which has a handler, is initialized before an EJB on which it has dependencies. This is caused by the way the EJB container initializes and loads EJB web services, the workaround is to rename the EJBs so that the EJB exposed as a web service is initialized after the EJB on which it has dependencies.

Log4j2 AsyncAppender thread does not die on tomcat undeploy causing memory leak

The stack I am using at the moment is:
log4j2 rc1
spring 3.2 core and web
tomcat 7.0.47
java 1.6.0_45
Windows 7
I don't have the ability to alter the tomcat version or java version and I would prefer not to alter the log4j version and spring version.
Essentially, when I undeploy my webapp I receieve a SEVERE warning saying:
SEVERE: The web application [/MyApp] appears to have started a thread named
[AsyncAppender-AsyncFile] but has failed to stop it. This is very likely to
create a memory leak
I can confirm that it does create a memory leak and this is what I am trying to fix.
So far I have attempted to create a custom ServletContextListener which contains the following code:
#Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Shutting down logger");
try {
((Log4jWebSupport) event.getServletContext().getAttribute(
Log4jWebSupport.SUPPORT_ATTRIBUTE)).clearLoggerContext();
((LifeCycle) LogManager.getContext()).stop();
} catch (Exception e) {
}
}
None of these two lines seems to fix the problem, however I can confirm that this code is being executed due to my sysout statement appearing in the tomcat console.
I am using log4j2 through an interceptor which I am setting up using Spring
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<ref bean="LoggingInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<bean id="LoggingInterceptor" class="MyLoggerClass">
The interceptor works correctly and the logs appear where I expect them to. My implementation of the logger is:
private static Logger log = LogManager.getLogger("MetricLogger");
public void log(LogPayload payload) {
if(payload != null){
log.info(payload.get());
}
}
Where LogPayload.get() returns a String.
As I am using the logging facility across multiple webapps I have created a separate jar file containing this and the classes recording the measurements. I have included this using maven and I compile it into the final war file I deploy to tomcat. This war file is included on a per app basis and is not included in the global tomcat/lib folder.
Does anyone have any insight as to why I get my memory leak issue and what the possible solutions are to fixing this?
Many thanks for your help and please let me know if you need further information.
The solution to this that I have so far found is that I need to include the following snippet in the web.xml.
<listener>
<listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
This is specific to servlet spec 2.5. This seems to resolve the memory leak issue.
In case you are facing this issue recently you should note the following:
If you are using servlet 3.0+ and tomcat > 7.0.43 or Tomcat 8 there are no configuration needed, you just have to provide the correct maven dependencies to make log4j2 aware of running in a webcontainer like the following (in addition we use slf4j):
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.0</version>
</dependency>
Since in our case the log4j-web artifact was missing we faced the same warning which said "... started a thread named [AsyncAppender-AsyncFile] but has failed to stop it ..."
After providing the mentioned dependencies the warning is gone.
you can read more about requirements here
Adding the below snippet worked for me to get rid of memory leak due to Async-Appender threads not getting shut down even after the application shutdown.
Thank you #kipper_t.
<listener>
<listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>

Problem using #Valid with Spring MVC application deployed to Tomcat

I am building a Spring MVC application and deploying to Tomcat. When I try to use the #Valid syntax, I get a compilation error:
Valid cannot be resolved to a type.
I am using Eclipse Java EE IDE for Web Developers (Helios SR2).
I have hibernate-validator.jar in my classpath, as the Spring documentation indicates, but I don't see javax.validation.* anywhere in my references.
Any help would be appreciated.
add
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
to your context and you have to have javax.validation.* classes on classpath
search for javax.validation in maven repositories or use following if you use Maven:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>com.springsource.javax.validation</artifactId>
<version>1.0.0.GA</version>
</dependency>

Can I get application.wadl file using RESTeasy?

I need to get WADL file for RESTful service. I know that in case using jersey it's available as http://localhost:8080/application.wadl. But I use RESTeasy.
Can I do the same in my framework case?
Latest versions:
Quoting Chapter 49. RESTEasy WADL Support:
Chapter 49. RESTEasy WADL Support
49.1. RESTEasy WADL Support for Servlet Container
49.2. RESTEasy WADL support for Sun JDK HTTP Server
49.3. RESTEasy WADL support for Netty Container
49.4. RESTEasy WADL Support for Undertow Container
RESTEasy has its own support to generate WADL for its resources, and it supports several different containers. The following text will show you how to use this feature in different containers.
49.1. RESTEasy WADL Support for Servlet Container
RESTEasy WADL uses ResteasyWadlServlet to support servlet container. It can be registered into web.xml to enable WADL feature. Here is an example to show the usages of ResteasyWadlServlet in web.xml:
<servlet>
<servlet-name>RESTEasy WADL</servlet-name>
<servlet-class>org.jboss.resteasy.wadl.ResteasyWadlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RESTEasy WADL</servlet-name>
<url-pattern>/application.xml</url-pattern>
</servlet-mapping>
The preceding configuration in web.xml shows how to enable
ResteasyWadlServlet and mapped it to /application.xml. And then the
WADL can be accessed from the configured URL:
/application.xml
Workaround for Older versions
There is a workaround: a maven plugin called maven-wadl-plugin by the jersey folks that also works to generate WADL for services coded using RESTEasy.
Here's how to use it.
1. Add this to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>maven-wadl-plugin</artifactId>
<version>1.17</version>
<executions>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
<phase>${javadoc-phase}</phase>
</execution>
</executions>
<configuration>
<wadlFile>${project.build.outputDirectory}/application.wadl
</wadlFile>
<formatWadlFile>true</formatWadlFile>
<baseUri>http://example.com:8080/rest</baseUri>
<packagesResourceConfig>
<param>com.example.rs.resource</param>
</packagesResourceConfig>
<wadlGenerators>
<wadlGeneratorDescription>
<className>com.sun.jersey.server.wadl.generators.WadlGeneratorApplicationDoc
</className>
<properties>
<property>
<name>applicationDocsFile</name>
<value>${basedir}/src/main/doc/application-doc.xml</value>
</property>
</properties>
</wadlGeneratorDescription>
<wadlGeneratorDescription>
<className>com.sun.jersey.server.wadl.generators.WadlGeneratorGrammarsSupport
</className>
<properties>
<property>
<name>grammarsFile</name>
<value>${basedir}/src/main/doc/application-grammars.xml</value>
</property>
</properties>
</wadlGeneratorDescription>
</wadlGenerators>
</configuration>
</plugin>
</plugins>
</build>
Pay attention to the baseUri and packagesResourceConfig elements. You have to change them to reflect your project's configuration. You may also want to change the plugin's version (I used 1.17).
2. Create a /doc folder and add some files.
Create the src/main/doc/ folder and create the two files below.
File: application-doc.xml
Content:
<?xml version="1.0" encoding="UTF-8"?>
<applicationDocs targetNamespace="http://wadl.dev.java.net/2009/02">
<doc xml:lang="en" title="A message in the WADL">This is added to the start of the generated application.wadl</doc>
</applicationDocs>
File: application-grammars.xml
Content:
<?xml version="1.0" encoding="UTF-8" ?>
<grammars xmlns="http://wadl.dev.java.net/2009/02" />
3. Run the maven command.
Go to the project folder and run the following command:
$ mvn compile com.sun.jersey.contribs:maven-wadl-plugin:generate
The files \target\classes\application.wadl (the WADL itself) and \target\classes\xsd0.xsd (the schema of the resources - it's used by the application.wadl) should be generated.
Edit and use them as you wish.
PS.: Bear in mind that this is a very simple use of the maven-wadl-plugin. It can do a lot more. To know it better, please refer to the zip file in http://search.maven.org/remotecontent?filepath=com/sun/jersey/samples/generate-wadl/1.12/generate-wadl-1.12-project.zip
WADL generation in RESTeasy is a feature not yet implemented. If you want it go vote for it.
https://issues.jboss.org/browse/RESTEASY-166
See RESTEasy WADL Support (3.1.0). The snipped below is copied from there
<servlet>
<servlet-name>RESTEasy WADL</servlet-name>
<servlet-class>org.jboss.resteasy.wadl.ResteasyWadlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RESTEasy WADL</servlet-name>
<url-pattern>/application.xml</url-pattern>
</servlet-mapping>
This uses the ResteasyWadlServlet and will make the WADL accessible at /application.xml.
Note:
Rex and Jaskirat have already mentioned previously that RESTEASY-166 was used to manage the implementation for this feature. It seems this was completed in 3.0.14.
we can generate a wadl with the help of maven project with POM.XML
https://issues.jboss.org/browse/RESTEASY-166 check the comments here..!!

Categories

Resources