1

I'm migrating a webapp from JBoss to Embedded Tomcat. It works on intellij but when I run the war file with java -jar myapplication.war it shows the following error. After googling I couldn't find any solution. This problem seems like I have two struts2-core jars or some dependencies conflicting but I have just one jar.

Sample project here.

Error:

 2017-12-11 10:58:24.527 ERROR 10296 --- [nio-8080-exec-1] o.apache.struts2.dispatcher.Dispatcher   : Dispatcher initialization failed
 
 com.opensymphony.xwork2.config.ConfigurationException: Unable to load configuration.
         at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70) ~[xwork-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:978) ~[struts2-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:446) ~[struts2-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:490) ~[struts2-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74) [struts2-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.dispatcher.ng.servlet.StrutsServlet.init(StrutsServlet.java:54) [struts2-core-2.3.34.jar!/:2.3.34]
         at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:795) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:133) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
         at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.14.jar!/:8.5.14]
         at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
 Caused by: com.opensymphony.xwork2.config.ConfigurationException: Unable to load bean: type: class:com.opensymphony.xwork2.ObjectFactory
         at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:247) ~[xwork-core-2.3.34.jar!/:2.3.34]
         at org.apache.struts2.config.StrutsXmlConfigurationProvider.register(StrutsXmlConfigurationProvider.java:102) ~[struts2-core-2.3.34.jar!/:2.3.34]
         at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:240) ~[xwork-core-2.3.34.jar!/:2.3.34]
         at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67) ~[xwork-core-2.3.34.jar!/:2.3.34]
         ... 23 common frames omitted
 Caused by: com.opensymphony.xwork2.config.ConfigurationException: Bean type class com.opensymphony.xwork2.ObjectFactory with the name struts has already been loaded by bean - jar:file:/C:/workspaces/workspace/pessoal/spring-boot-struts2/target/spring-boot-struts2-0.0.1-SNAPSHOT.war!/WEB-INF/lib/struts2-core-2.3.34.jar!/struts-default.xml:65:72
         at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:231) ~[xwork-core-2.3.34.jar!/:2.3.34]
         ... 26 common frames omitted

My relevant stuffs:

StrutsServlet:

@WebServlet(urlPatterns = { "*.do" })
public class SBSStrutsServlet extends StrutsServlet {

    private static final long serialVersionUID = 4919365268043339311L;

}

Application.java:

@SpringBootApplication
@ServletComponentScan
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

struts.xml:

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <constant name="struts.objectFactory" value="spring"/>

    <package name="sbs" namespace="/sbs" extends="struts-default">
        <action name="welcome" class="com.gbarbosa.sbs.controller.HelloWorldAction">
            <result name="success">welcome.jsp</result>
        </action>
    </package>
</struts>

WEB-INF\lib:

asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
classmate-1.3.3.jar
commons-fileupload-1.3.2.jar
commons-io-2.2.jar
commons-lang3-3.2.jar
ecj-4.5.1.jar
freemarker-2.3.26-incubating.jar
hibernate-validator-5.3.5.Final.jar
jackson-annotations-2.8.0.jar
jackson-core-2.8.8.jar
jackson-databind-2.8.8.jar
javassist-3.11.0.GA.jar
jboss-logging-3.3.1.Final.jar
jcl-over-slf4j-1.7.25.jar
jstl-1.2.jar
jul-to-slf4j-1.7.25.jar
log4j-api-2.7.jar
log4j-core-2.8.2.jar
log4j-over-slf4j-1.7.25.jar
logback-classic-1.1.11.jar
logback-core-1.1.11.jar
ognl-3.0.21.jar
slf4j-api-1.7.25.jar
snakeyaml-1.17.jar
spring-aop-4.3.8.RELEASE.jar
spring-beans-4.3.8.RELEASE.jar
spring-boot-1.5.3.RELEASE.jar
spring-boot-autoconfigure-1.5.3.RELEASE.jar
spring-boot-starter-1.5.3.RELEASE.jar
spring-boot-starter-logging-1.5.3.RELEASE.jar
spring-boot-starter-web-1.5.3.RELEASE.jar
spring-context-4.3.8.RELEASE.jar
spring-core-4.3.8.RELEASE.jar
spring-expression-4.3.8.RELEASE.jar
spring-web-4.3.8.RELEASE.jar
spring-webmvc-4.3.8.RELEASE.jar
struts2-core-2.3.34.jar
struts2-spring-plugin-2.3.34.jar
tomcat-embed-core-8.5.14.jar
tomcat-embed-el-8.5.14.jar
tomcat-embed-jasper-8.5.9.jar
validation-api-1.1.0.Final.jar
xwork-core-2.3.34.jar

WAR structure final:

META-INF
org
sbs
WEB-INF

I'm really stuck on this and on IntelliJ It works fine. I have no idea why Struts has already created a bean called struts and of type com.opensymphony.xwork2.ObjectFactory.

Please, someone has any idea?

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • It's created by the dispatcher when the framework is started. If it fails, then you have something wrong with the configuration or dependencies. – Roman C Dec 13 '17 at 15:20
  • I believe It's something in my packing build on maven because when I build as an executable jar Struts starts well and the action is called but I can't use an executable jar because It doesn't serve JSP pages, It just find the JSP pages if I put my src\main\webapp folder in the same directory of my jar file. – George Barbosa Dec 13 '17 at 19:10
  • You can't, because you missing them. – Roman C Dec 14 '17 at 01:10
  • Sorry, I didn't understand. I would like to build as an executable war. Isn't it possible? – George Barbosa Dec 14 '17 at 19:24
  • How did you build an executable war? – Roman C Dec 14 '17 at 19:48
  • I'm using the spring-boot-maven-plugin to repackage it. – George Barbosa Dec 15 '17 at 17:42

2 Answers2

1

I have found the solution.

Although of It looks like a duplicate jar issue It is not. The problem there is: tomcat container is providing two different paths to the same file. Different prefix paths jar:file:/ and jar:war:file:/.

Bean type class com.opensymphony.xwork2.ObjectFactory with the name spring has already been loaded by bean - jar:file:/C:/target/spring-boot-struts2-0.0.1-SNAPSHOT.war!/WEB-INF/lib/struts2-spring-plugin-2.3.34.jar!/struts-plugin.xml:29:132 - bean - jar:war:file:/C:/target/spring-boot-struts2-0.0.1-SNAPSHOT.war*/WEB-INF/lib/struts2-spring-plugin-2.3.34.jar!/struts-plugin.xml:29:132

To solve that I just changed the struts2-core and struts2-spring-plugin scope from compile to provided. The spring-boot-maven-plugin put these files under WEB-INF/lib-provided then when I run with java -jar myapplication.war these jars are provided in runtime.

0

To make executable jar or war from the maven project, you should use

   <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <executable>true</executable>
            <classifier>boot</classifier>
        </configuration>
    </plugin>

which allows you repackage war file to make it bootable. You can find more about Spring Boot Maven plugin on this page or on the Usage page.

66.2 Packaging executable jar and war files

Once spring-boot-maven-plugin has been included in your pom.xml it will automatically attempt to rewrite archives to make them executable using the spring-boot:repackage goal. You should configure your project to build a jar or war (as appropriate) using the usual packaging element:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- ... -->
    <packaging>jar</packaging>
    <!-- ... -->
</project>

Your existing archive will be enhanced by Spring Boot during the package phase. The main class that you want to launch can either be specified using a configuration option, or by adding a Main-Class attribute to the manifest in the usual way. If you don’t specify a main class the plugin will search for a class with a public static void main(String[] args) method.

To build and run a project artifact, you can type the following:

$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.jar
Roman C
  • 49,761
  • 33
  • 66
  • 176