Search code examples
javamavenstruts2weblogicapache-tiles

Struts2-tiles-plugin 2.3.28 - StrutsTilesListener throws NullPointerException


I am upgrading from struts-2.3.24.1 to struts-2.3.28 and in doing so had to upgrade tiles from 2.1.2 to 2.2.2. I deploy on WebLogic Server 12.1.3. My application is built with no errors using maven 3, however when I deploy, it generates the following errors:

<User defined listener org.apache.struts2.tiles.StrutsTilesListener failed: java.lang.NullPointerException.java.lang.NullPointerException
    at java.io.File.<init>(Unknown Source)
    at org.apache.struts2.tiles.StrutsWildcardServletTilesApplicationContext.<init>(StrutsWildcardServletTilesApplicationContext.java:53)

Nothing has changed in the application since it worked with struts 2.3.24.1. There are .jsp files in the location referenced in the tiles-defs.xml. I have tried many different approaches to fix this, but keep getting the same error. I also haven't seen this particular issue discussed before. What else do I need to change with his particular upgrade? What am I missing?

Thank you,

Full Stacktrace:

    <User defined listener org.apache.struts2.tiles.StrutsTilesListener failed: java.lang.NullPointerException.java.lang.NullPointerException
    at java.io.File.<init>(Unknown Source)
    at org.apache.struts2.tiles.StrutsWildcardServletTilesApplicationContext.<init>(StrutsWildcardServletTilesApplicationContext.java:53)
    at org.apache.struts2.tiles.StrutsTilesInitializer.createTilesApplicationContext(StrutsTilesInitializer.java:37)
    at org.apache.tiles.startup.AbstractTilesInitializer.initialize(AbstractTilesInitializer.java:68)
    at org.apache.tiles.web.startup.AbstractTilesListener.contextInitialized(AbstractTilesListener.java:62)
    at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:678)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.EventsManager.executeContextListener(EventsManager.java:243)
    at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:200)
    at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:185)
    at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1838)
    at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:2876)
    at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1661)
    at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:823)
    at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
    at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
    at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:42)
    at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)
    at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
    at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:216)
    at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:211)
    at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:42)
    at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:73)
    at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:24)
    at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:729)
    at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:42)
    at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:258)
    at weblogic.application.internal.SingleModuleDeployment.activate(SingleModuleDeployment.java:48)
    at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:165)
    at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:80)
    at weblogic.deploy.internal.targetserver.BasicDeployment.activate(BasicDeployment.java:226)
    at weblogic.deploy.internal.targetserver.BasicDeployment.activateFromServerLifecycle(BasicDeployment.java:418)
    at weblogic.management.deploy.internal.DeploymentAdapter$1.doActivate(DeploymentAdapter.java:51)
    at weblogic.management.deploy.internal.DeploymentAdapter.activate(DeploymentAdapter.java:200)
    at weblogic.management.deploy.internal.AppTransition$2.transitionApp(AppTransition.java:30)
    at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:240)
    at weblogic.management.deploy.internal.ConfiguredDeployments.activate(ConfiguredDeployments.java:169)
    at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:123)
    at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:210)
    at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:118)
    at weblogic.server.AbstractServerService.postConstruct(AbstractServerService.java:78)
    at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.glassfish.hk2.utilities.reflection.ReflectionHelper.invoke(ReflectionHelper.java:1017)
    at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java:388)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:430)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456)
    at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:225)
    at org.glassfish.hk2.runlevel.RunLevelContext.findOrCreate(RunLevelContext.java:82)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2488)
    at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:98)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:606)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:77)
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:231)
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:254)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:413)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456)
    at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:225)
    at org.glassfish.hk2.runlevel.RunLevelContext.findOrCreate(RunLevelContext.java:82)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2488)
    at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:98)
    at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:87)
    at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.oneJob(CurrentTaskFuture.java:1162)
    at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run(CurrentTaskFuture.java:1147)
    at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpOneLevel.run(CurrentTaskFuture.java:753)
    at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:553)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)

pom.xml excerpt

    <properties>
    <struts2-version>2.3.28</struts2-version>
    <tiles-version>2.2.2</tiles-version>
    </properties>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>${struts2-version}</version>
        <exclusions>
            <exclusion>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-convention-plugin</artifactId>
        <version>${struts2-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-junit-plugin</artifactId>
        <version>${struts2-version}</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-rest-plugin</artifactId>
        <version>${struts2-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-spring-plugin</artifactId>
        <version>${struts2-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-tiles-plugin</artifactId>
        <version>${struts2-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-jsp</artifactId>
        <version>${tiles-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-core</artifactId>
        <version>${tiles-version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-el</artifactId>
        <version>${tiles-version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-freemarker</artifactId>
        <version>${tiles-version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-ognl</artifactId>
        <version>${tiles-version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-api</artifactId>
        <version>${tiles-version}</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-servlet</artifactId>
        <version>${tiles-version}</version>
    </dependency>   

Struts.xml

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

<constant name="struts.enable.DynamicMethodInvocation" value="TRUE" />

<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" class="path.mapper.GfpDynamicMapper" name="gfpDynamicMapper"/>
<constant name="struts.mapper.class" value="gfpDynamicMapper" /> 

<constant name="struts.convention.action.includeJars" value=".*_wl_cls_gen.*"/>
<constant name="struts.convention.action.fileProtocols" value="jar,zip" />


<constant name="struts.convention.action.suffix" value="Controller" />
<constant name="struts.convention.action.mapAllMatches" value="true" />
<constant name="struts.convention.default.parent.package" value="default" />
<constant name="struts.custom.i18n.resources" value="path/application-gfp" />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.convention.result.path" value="tiles/gfp"/>


<!-- Handler setup -->
<bean name="gfpXml"  type="org.apache.struts2.rest.handler.ContentTypeHandler" class="path.handler.GfpXmlHandler" />
<bean type="com.opensymphony.xwork2.UnknownHandler" name="handler" class="path.handler.UnknownHandler"/>
<package name="default" namespace="/actions" extends="rest-default">
    <result-types>
        <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
    </result-types>

    <interceptors>

        <interceptor name="userInterceptor"  class="path.interceptors.UserInterceptor" />

        <interceptor name="exceptionMapper" class="path.interceptors.ExceptionMappingInterceptor">
            <param name="logEnabled">true</param>
        </interceptor>

        <interceptor name="cachingHeadersInterceptor" class="path.interceptors.CachingHeadersInterceptor"/>
        <interceptor-stack name="interceptorStack">
            <interceptor-ref name="exceptionMapper"/>
            <interceptor-ref name="tokenSession" >
                <param name="excludeMethods">create,edit,index,show,compare,ulns,showInvalidUlns,toggleExternalUics,status,exportSummary,summary,exportSlice,exportSlices,export,exportUlns,exportPids,exportPcode,exportArt,exportAst,exportDrrs,exportOrgAssoc,exportBillet,exportEquipment,exportLeaderAssoc,exportGfmts,exportSorts,exportUSMCSliderPull,exportWebSked,exportExcel,exportSliceCompare,exportSliceCompareCritieria,exportCargo,exportPersonnel,showSliceSummary</param>
            </interceptor-ref>
            <interceptor-ref name="alias"/>
            <interceptor-ref name="userInterceptor"/>
            <interceptor-ref name="servletConfig"/>
            <interceptor-ref name="messages">
                <param name="operationMode">AUTOMATIC</param>
            </interceptor-ref>
            <interceptor-ref name="prepare"/>
            <interceptor-ref name="i18n"/>
            <interceptor-ref name="chain"/>
            <interceptor-ref name="debugging"/>
            <interceptor-ref name="profiling"/>
            <interceptor-ref name="scopedModelDriven"/>
            <interceptor-ref name="modelDriven">
                <param name="refreshModelBeforeResult">true</param>
            </interceptor-ref>
            <interceptor-ref name="fileUpload"/>
            <interceptor-ref name="checkbox"/>
            <interceptor-ref name="multiselect"/>
            <interceptor-ref name="staticParams"/>
            <interceptor-ref name="actionMappingParams"/>
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*,statusCode,token,struts.token.name,import,submit,label.next,label.back,_method</param>
            </interceptor-ref>
            <interceptor-ref name="rest" />
            <interceptor-ref name="conversionError"/>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse,index,show,edit,editNew</param>
            </interceptor-ref>
            <interceptor-ref name="restWorkflow">
                <param name="excludeMethods">input,back,cancel,browse,index,show,edit,editNew</param>
            </interceptor-ref>
            <interceptor-ref name="annotationWorkflow"/>
            <interceptor-ref name="cachingHeadersInterceptor"/>
        </interceptor-stack>
      </interceptors>
</package>
</struts> 

web.xml

<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
    <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
    <param-value>/WEB-INF/classes/path/tiles-defs.xml</param-value>
</context-param>    
<listener>
    <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>

tiles-defs.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
    <definition name="layout.default" template="/WEB-INF/tiles/common/default.jsp">
        <put-attribute name="infoKey" value="" />
        <put-attribute name="titleKey" value="" />
        <put-attribute name="browserTitleKey" value="" />
        <put-attribute name="header" value="/WEB-INF/tiles/common/header.jsp" />
        <put-attribute name="content" value="" />
        <put-attribute name="menubar" value="" />
        <put-attribute name="adminMenu" value="" />
        <put-attribute name="footer" value="/WEB-INF/tiles/common/footer.jsp" />
</definition>
<definition name="layout.update" template="/WEB-INF/tiles/common/updateDefault.jsp">
    <put-attribute name="infoKey" value="" />
    <put-attribute name="titleKey" value="" />
    <put-attribute name="header" value="/WEB-INF/tiles/common/classmarkTop.jsp"/>
    <put-attribute name="content" value="" />
    <put-attribute name="menubar" value="" />
    <put-attribute name="footer" value="/WEB-INF/tiles/common/footer.jsp" />
</definition>
<definition name="layout.admin" extends="layout.default">
    <put-attribute name="adminMenu" value="/WEB-INF/tiles/gfp/admin/adminMenu.jsp" />
    </definition>
</tiles-definitions>

Edit: this is not related to the what is a Null Pointer Exception question referenced in the comments, because this is an issue with struts and tiles configurations.

Edit 3/31/2016 : I turned on remote debugging and found that the context has all the appropriate paths (see image below). However, line 53 of StrutsWildcardServletTilesApplicationContext.java the context.getRealPath() is returning null since it can't get the absolute path to this resource. The context path is also correct within the context object. I read that the getRealPath() function can return null if it can't translate the virtual path to a real path which occurs when files are coming from a .war. How do I correct this?

Image of remote debugging


Solution

  • Just resolved the NPE issue I was having. As I stated above it was an issue with the getRealPath not being able to convert the virtual path to the absolute path. I used the advice from this thread.

    Why does getRealPath() return null when deployed with a .war file?

    and added the configuration

    <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
    

    to my weblogic.xml.