On starting up my Web app with Velocity 2.0 I'm getting the following error:
Caused by: java.lang.NoClassDefFoundError:
org/apache/velocity/runtime/log/CommonsLogLogChute
at org.springframework.ui.velocity.VelocityEngineFactory.createVelocityEngine(VelocityEngineFactory.java:240)
at org.springframework.ui.velocity.VelocityEngineFactoryBean.afterPropertiesSet(VelocityEngineFactoryBean.java:60)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 34 more
All dependencies have been satisfied. We are using
slf4j-api-1.7.25.jar
slf4j-simple-1.7.25.jar
commons-lang3-3.5.jar
commons-io-2.5.jar
commons-logging-1.2.jar (yes we do have Commons-Logging)
In applicationContext.xml the velocityEngine bean is defined as follows
<bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean"/>
Any thoughts on this?
My file velocity-engine-core-2.0.jar only contains the following .runtime subpackages:
defaults, directive, parser, resource, visitor
but no log .
UPDATE The following overrideLogging = FALSE in the Spring Velocity Engine bean declaration solved the problem. But why?
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="overrideLogging" value="false" />
</bean>
I just followed a tip on
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/ui/velocity/VelocityEngineFactory.html
but not sure what happened.
When overrideLogging is true, the class org.apache.velocity.runtime.log.CommonsLogLogChute is still required by Spring while it has disappeared in Velocity 2.0, since Velocity now uses the slf4j logging framework.
You'll need to wait for an update of the Spring Velocity classes if you need overrideLogging to be true.
Edit on June 21st, 2022 - Since version 2.3, Velocity does provide Spring support.
Velocity made a change in logging:
Make Velocity use the base logger namespace 'org.apache.velocity'
unless specified with runtime.log.name in the configuration, and have
the runtime instance log with this base namespace, and other modules
log with children namespaces
CommonsLogLogChute added in before major version velocity 1.7:
Add a CommonsLogLogChute that allows logging through commons-logging.
So you probably have an old jar or configuration in your runtime environment.
Alibaba implemented a support context package for that case: https://github.com/alibaba/spring-velocity-support
Just add to maven:
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<!-- Spring Context Velocity -->
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-velocity</artifactId>
<version>1.4.3.18.RELEASE</version>
</dependency>
But beware that your project now uses Velocity 2.0.
Related
Trying to deploy a Spring Boot app on Tomcat (not the embedded Tomcat). I have configured a Java mail session on the Tomcat server config, and I'm trying to access it as a JNDI value in my app. For some reason, my app gets an error and shows this:
Caused by: java.lang.IllegalArgumentException: The local resource link [support] that refers to global resource [mail/support] was expected to return an instance of [javax.mail.Session] but returned an instance of [javax.mail.Session]
at org.apache.naming.factory.ResourceLinkFactory.getObjectInstance(ResourceLinkFactory.java:163)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:840)
I have included javax.mail.jar in the Tomcat /lib folder. I also have spring-boot-starter-mail included in my pom.xml
I've tried removing the javax.mail.jar from Tomcat's lib, but that causes an error on Tomcat start because it can't create the mail session. I've also tried removing spring-boot-starter-mail, but that interferes with some of my code that requires JavaMailSender and other mail components. I've tried messing with the JNDI import and stuff like that, but to no avail. I've also tried checking the version of the mail jar included by spring-boot-starter-mail, and updating the jar in Tomcat to match. I've also checked my transitive dependencies in Maven to see if a different mail implementation is being pulled in, and there's nothing. So I'm kind of all out of ideas.
Here's where I'm getting the JNDI value in my web.xml:
<resource-ref>
<description>The mail session configured in Tomcat</description>
<res-ref-name>mail/support</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Here's what I have configured in Tomcat's server.xml:
<GlobalNamingResources>
<Resource name="mail/support"
auth="Container"
type="javax.mail.Session"
mail.smtp.host="smtp.XXX.XXX"
mail.smtp.user="support"
mail.smtp.from="support#XXX.org" />
</GlobalNamingResources>
And here's what's in context.xml:
<Context>
<ResourceLink global="mail/support" name="mail/support" type="javax.mail.Session" />
</Context>
I'd like to be able to use spring-boot-starter-mail, and use a globally configured JNDI mail session. I don't know if those are just incompatible wishes, but I don't see why they should be.
Ok, so the solution was indeed what #Bill Shannon suggested. I had to include the com.sun.mail dependency with the Maven provided scope. My particular issue was that the project was already using the spring-boot-starter-mail dependency, which includes the com.sun.mail jar. So I had to exclude that from my Maven dependency. So the complete Maven dependency related to mail stuff looks like this:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</exclusion>
</exclusions>
</dependency>
That seems a little obvious now. I think my main source of confusion was the weird Tomcat error message. Thanks for anyone who took a look at this, hopefully this resolves the issue for someone else!
I'm setting up an example project for testing purposes which uses Weld SE and JUnit5 and for some reason, in my test classes, after initializing weld I observ that, for some reason, it's bean discovery is disabled, which in the end, it lead me to this error:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Person with qualifiers #Default;
This is my test class :
#EnableWeld
public class SimpleTestA {
#Inject
Person p;
#Test
public void testThatItWorks() {
System.out.println("Hey");
}
}
located in :
projectName\core\model\src\test\java\com\aCompany\projectName\core\model\testmodel\SimpleTestA.java
This is my beans.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_1.xsd" version="1.1" bean-discovery-mode="all" />
located in :
projectName\core\model\src\main\resources\META-INF\beans.xml
The project structure is fairly simple, I just have a main module named "projectName" which is the parent of the sub-module named "core" which contains all that i pasted earlier. My dependencies list is this :
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.aggregator.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>${weld.se.core.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.weld/weld-junit5 -->
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-junit5</artifactId>
<version>${weld.junit5.version}</version>
<scope>test</scope>
</dependency>
and those are my properties :
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<weld.se.core.version>3.0.1.Final</weld.se.core.version>
<weld.junit5.version>1.3.1.Final</weld.junit5.version>
<junit-jupiter.aggregator.version>5.4.0</junit-jupiter.aggregator.version>
If I modify the test adding the weld initialization attribute with explicit bean discovery activation, everything works very well:
#WeldSetup
WeldInitiator weldInitiator = WeldInitiator.of(WeldInitiator.createWeld().enableDiscovery());
What I'm missing ? If the beans.xml is present, shouldn't the bean discovery activated automatically? Thank you in advance.
So the thing here is that you are using Weld SE (well, weld-junit is), not Weld EE which you might know from servers such as WildFly.
In SE, the discovery is by default off and so called synthetic archive is used.
Synthetic archive only contains whatever you yourself feed it - classes as beans, packages to scan through etc. It doesn't scan whole classpath.
So to make your example work, you can either have the discovery on, or you can add the classes and packages you need via Weld.addPackages(), Weld.addClasses() and so on.
In context of Weld-junit this translates into WeldInitiator.createWeld().addPackages().
The reason why Weld SE (and weld-junit) doesn't perform the whole discovery is because you would effectively scan whole classpath including JDK packages and all. That takes time and on top of that you also discover tons of beans you don't need. Or you can pick up interceptors/alternatives that you didn't mean to. Last but not least, these are meant to be unit tests, so minimal deployments that test your beans.
When I run .war file in tomcat, the logs show
ERROR [com.configleon.configurer.WebPropertyConfigurer] - The 'configLocation' variable is not specified in the JVM settings!
ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
And this my code :
<!-- configlion property configurator -->
<bean class="com.configleon.configurer.WebPropertyConfigurer">
<property name="propertyResources">
<bean class="com.configleon.resource.WebPropertyResources"/>
</property>
</bean>
Anyone can help me please ?
for first one ERROR [com.configleon.configurer.WebPropertyConfigurer]
see the here
and for second one
ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
in deployment environment, just make sure your server classpath has included the Spring jar library (e.g spring-2.5.6.jar).
For Spring3, ContextLoaderListener is moved to spring-web.jar, you can get the library from Maven central repository.
Markup
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
I use Apache Felix and weld-osgi for a Java SE application. The problem is that in injected bean I use #ApplicationScoped from package javax.enterprise.context.ApplicationScoped. But there is no such package in weld-osgi-bundle-2.1.2.Final.
This package exist in weld-se but it's not in the OSGi bundle. How can I solve this problem?
I would try running the following dependency as separate bundle:
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.1-20130918</version>
</dependency>
(Maven Central link)
Be careful, you need version 1.1-20130918. Version 1.1 does not have OSGi headers in the MANIFEST.MF. You can unzip the jar and check the META-INF/MANIFEST.MF file for OSGi headers like Bundle-ManifestVersion and Bundle-SymbolicName. You can also check here the required packages of that bundle, it's in the Import-Packages header.
How to figure out
Check the dependencies of weld-osgi-bundle on Maven Central (or in its pom.xml). It contains the following:
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-api</artifactId>
</dependency>
This weld-api refers to the cdi-api above which contains the missing annotation:
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</dependency>
Another way is pressing F3 (Open Declaration) in Eclipse while the cursor in the ApplicationScoped annotation then in the Project Explorer View enable the Link with Editor and it will show that ApplicationScoped.class is inside the cdi-api-1.1.jar.
Finding OSGi version of another jars
You probably need more bundles than this one (transitive dependencies or it was only the first one which stopped the installation).
Not all well-known jar has OSGi headers, like the following one:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
In that case search for the group id on Maven Central. Two results which contain the javax.inject package and have OSGi headers:
org.glassfish.hk2.external
org.apache.servicemix.bundles
If you can't find anything you can convert any jar to OSGi bundle by hand. Actually, you can do this with the weld-se.jar but installing dependencies separately looks cleaner.
I have a web service project implemented in java and it also contains jsp pages. I deploy it on jetty 8.1.5 on my machine and it works normally. But when I deploy on a windows server 2003 with jetty 8.1.3 it gives this exception:
org.apache.jasper.el.ELContextImpl cannot be cast to org.apache.jasper.runtime.ELContextImpl
This is the full trace:
java.lang.ClassCastException: org.apache.jasper.el.ELContextImpl cannot be cast to org.apache.jasper.runtime.ELContextImpl
at org.apache.jasper.runtime.PageContextImpl.evaluateExpression(PageContextImpl.java:1002)
at org.apache.jsp.home.index_jsp._jspService(org.apache.jsp.home.index_jsp:52)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:542)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:271)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:98)
at org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:557)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:735)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:499)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:350)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)
at java.lang.Thread.run(Unknown Source)
Any idea what is this exception and how to fix it?
That can happen if your webapp ships with servletcontainer-specific JAR files such as jasper.jar, jetty.jar servlet.jar, etc in the /WEB-INF/lib for some unclear reason. This is in turn conflicting with with a different versioned JAR file on the target servletcontainer.
Remove that servletcontainer-specific JAR file from your webapp's /WEB-INF/lib. It doesn't belong there. It's supposed to be already supplied by the servletcontainer itself.
See also:
How do I import the javax.servlet API in my Eclipse project? (this doesn't exactly answer your concrete problem, but this is at least technically the same core problem which should give you a better understanding of this common starter's mistake)
IF you are using maven (I asked on a comment without response), you can avoid conflictive jars using a "provided" scope. When you deploy it for production, jars are not included.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
I'm not sure about jetty's jars but it's probably the same.
IF you are NOT using maven, you should move your conflictive jars (servlets and jetty) to your develompent container lib folder and remove them from your applications WEB-INF/lib folder.
If the folder /WEB-INF/lib of your webapp does not contain a jasper.jar (see BalusC' answer), please check whether another webapp is running in your container. Then check if that webapp contains a jasper.jar in its folder /WEB-INF/lib. This happened to us. Be removing jasper.jar from those webapps (sic!), the problem could be solved. Obviously, the webapps are not that isolated for meach other as they should be. The problem appeared as we switched from Tomcat6 to Tomcat7 and jasper.jar (version 6) was bundled accidently with one of our webapps.
Apart from the answers mentioned watch out for one more thing. I've another war deployed under the same Tomcat 7.0.42 instance which had a jsp-2.1-6.0.2.jar under its WEB-INF/lib. This jar has org.apache.jasper.runtime.ELContextImpl class.
My understanding was that each webapp has its own classloader and the class files loaded by one webapp is not visible to the other webapp. Still as nothing was working I removed the other war which had that jsp.jar and restarted my tomcat and to my surprise the exception was no longer coming. Somehow this class was getting loaded and causing the issue.
The interesting thing is that both of these wars work perfectly fine in Tomcat 6.x.
I faced the same problem and tried all suggestions, none worked for me. I finally found out that the issue was caused after using Spring Boot overriding my tomcat version, as I had
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.0.M2</version>
Removing the Spring Boot solves the problem. This answer could provide the solution for using Spring Boot + Maven + Tomcat 8.
For me (Jetty 8.1.14), this exact error message was actually caused by another webapp in the same Jetty container. Are you running more than one webapps?
Add this line in <context>:
<Loader delegate="true" />
This problem is related with a conflicted jars in the applications
tag. This looks like:
<?xml version='1.0' encoding='utf-8'?>
<!-- The contents of this file will be loaded for each web application -->
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Loader delegate="true" /> <!--this line-->
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<!-- Uncomment this to enable Comet connection tacking (provides events on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->
</Context>