struts2-rest plugin..making both struts actions + rest actions work together but. giving java.lang.reflect.InvocationTargetException - rest

I am converting my existing struts 2 application to serve through some rest based services also.
I have used two plugins, struts2-rest plugin and struts-convention plugin,
Along with these I have also used asm.jar because above was giving a class not found exception which was there in asm jar.
I want to have both the functionalities as ..my normal struts action mappings should also work along with rest urls.
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- Overwrite Convention -->
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.mapper.class"value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts" />
<package name="userlogin" extends="struts-default" namespace="/">
<action>
......
</action>
</package>
<package name="secureAction" extends="struts-default,json-default"
namespace="/secure">
<interceptors>
...............
</interceptors>
<default-interceptor-ref name="secureStack" />
<global-results>
.............
</global-results>
<global-exception-mappings>
..............
</global-exception-mappings>
</package>
<include file=".....xml" />
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
.........
<display-name>strutsTest</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
....
</welcome-file-list>
<servlet>
<description></description>
<display-name>Logger</display-name>
<servlet-name>Logger</servlet-name>
<servlet-class>...........</servlet-class>
<init-param>
<param-name>log4j-properties-location</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Logger</servlet-name>
<url-pattern>/Logger</url-pattern>
</servlet-mapping>
I m not able to find any error..
what i see on screen when i run either struts action based mapping or rest url ..is :
Struts has detected an unhandled exception:
Messages:
com.thoughtworks.xstream.XStream
com/thoughtworks/xstream/XStream
java.lang.reflect.InvocationTargetException
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
File: org/apache/catalina/loader/WebappClassLoader.java
Line number: 1,516

ive solved the problem with customMapper..
this is my custom mapper class....
package org.apache.struts2.rest.example;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
import com.opensymphony.xwork2.config.ConfigurationManager;
public class CustomActionMapper extends DefaultActionMapper {
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
return getActionMapper(request, configManager).getMapping(request, configManager);
}
private ActionMapper getActionMapper(HttpServletRequest request, ConfigurationManager configManager) {
ActionMapping actionMapping = new ActionMapping();
parseNameAndNamespace(request.getRequestURI(), actionMapping, configManager);
if (!(actionMapping.getNamespace()).contains("/rest")) {
return container.getInstance(ActionMapper.class, "struts");
}
else
{
return container.getInstance(ActionMapper.class, "rest");
}
}
...........................................
my struts.xml is as follows......
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- Overwrite Convention -->
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="myActionMapper" class="org.apache.struts2.rest.example.CustomActionMapper" />
<constant name="struts.mapper.class" value="myActionMapper" />
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.convention.package.locators" value="example"/>
<constant name="struts.action.extension" value="xhtml,,xml,json,action"/>
<!-- overwrite action complete -->
<!-- normal struts actions -->
<package name="userlogin" extends="struts-default" namespace="/">
<action name="*">
<result name="error">/view/error/error.jsp</result>
</action>
..................
</package>
<include file="..........xml" />
<include file=".............xml" />
<!-- normal stryts actions complete -->
</struts>
these are the libraries im using ..
- asm-3.1.jar
- asm-commons-3.1.jar
- commons-beanutils-1.7.0.jar
- commons-collections-3.1.jar
- commons-fileupload-1.2.2.jar
- commons-io-2.0.1.jar
- commons-lang-2.5.jar
- commons-logging-1.1.1.jar
- commons-logging-api-1.1.jar
- ezmorph-1.0.3.jar
- freemarker-2.3.16.jar
- javassist-3.11.0.GA.jar
- json-lib-2.1-jdk15.jar
- log4j-1.2.8.jar
- ognl-3.0.1.jar
- struts2-convention-plugin-2.2.3.jar
- struts2-core-2.2.3.jar
- struts2-json-plugin-2.2.3.jar
- struts2-rest-plugin-2.2.3.jar
- xpp3_min-1.1.3.4.O.jar
- xstream-1.2.2.jar
- xwork-core-2.2.3.jar
make sure you use compatible library versions....

Related

Log4j and EAR conflicts with jboss

I have an EAR deployed on Jboss 4.2.3 with the following jboss-app.xml configuration file :
<jboss-app>
<loader-repository>
com.al6:loader=MyProject.ear
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</jboss-app>
And an application.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_1_4.xsd"
version="1.4">
<description>Manages project business layer</description>
<display-name>MyProject</display-name>
<module>
<ejb>MyProject.jar</ejb>
</module>
</application>
And in my Jboss log file :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- ===================================================================== -->
<!-- -->
<!-- Log4j Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- $Id: jboss-log4j.xml 75507 2008-07-08 20:15:07Z stan.silvert#jboss.com $ -->
<!--
| For more configuration infromation and examples see the Jakarta Log4j
| owebsite: http://jakarta.apache.org/log4j
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<!-- ================================= -->
<!-- Preserve messages in a local file -->
<!-- ================================= -->
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/server.log"/>
<param name="Append" value="false"/>
<param name="Threshold" value="INFO"/>
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="INFO" />
<appender-ref ref="FILE"/>
</root>
</log4j:configuration>
Until now, all the logging output was using "System....println", which is not a good practice at all.
So, I tried to change to logger.info with :
protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(getClass());
But, after that, I'm not gonna had any log at all, nothing.
I tried to add a category in the jboss log configuration file, like :
<category name="com.myproject">
<priority value="INFO" />
<appender-ref ref="FILE"/>
</category>
But nothing change.
So I used my own log4j implementation observing a log4j.properties file which I can modify without redeploy :
package com.myproject;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Log4jConfigurator implements Runnable {
private static final Logger logger = Logger.getLogger(Log4jConfigurator.class);
private final Path log4jConfigPath;
public Log4jConfigurator(String log4jConfigFile) {
this.log4jConfigPath = Paths.get(log4jConfigFile).toAbsolutePath();
}
#Override
public void run() {
try {
WatchService watcher = log4jConfigPath.getParent().getFileSystem().newWatchService();
log4jConfigPath.getParent().register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (!Thread.currentThread().isInterrupted()) {
WatchKey key = watcher.take();
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY &&
log4jConfigPath.getFileName().toString().equals(event.context().toString())) {
logger.info("Reloading log4j configuration from file: " + log4jConfigPath);
PropertyConfigurator.configure(log4jConfigPath.toString());
}
}
key.reset();
}
} catch (InterruptedException e) {
logger.info("Log4j configuration monitoring thread interrupted.");
} catch (Exception e) {
logger.error("Error while monitoring log4j configuration file", e);
}
}
}
It works perfectly !
BUT, two problems :
1-
I used the same file that Jboss used (server.log), it seems to work but is this ok to write log from jboss and my own log4j in the same file ?
2-
All the log from this are messed up by log4j I presume, and so I had twice informations :
2023-01-25 17:24:44,493 INFO [STDOUT] [ INFO] com.myproject.someBusiness:938 - getOrder
2023-01-25 17:24:44,546 INFO [STDOUT] [ INFO] com.myproject.someBusiness:3138 - prices are refreshed
I already delete the date in log4j xml configuration file to not having twice the log date.
But for the rest (INFO...), it's all contained in the %m variable, so I can't do anything.
Why jboss add it's own prefix ?
Seems to work with this solution :
I put my log4j.properties into /opt/jboss/server/myserverinstance/conf/ directory.
I ask to Jboss to check this log4j.properties file instead of the old jboss-log4j.xml.
In jboss-service.xml :
<!-- ==================================================================== -->
<!-- Log4j Initialization -->
<!-- ==================================================================== -->
<mbean code="org.jboss.logging.Log4jService"
name="jboss.system:type=Log4jService,service=Logging"
xmbean-dd="resource:xmdesc/Log4jService-xmbean.xml">
<attribute name="ConfigurationURL">resource:log4j.properties</attribute>
<attribute name="Log4jQuietMode">true</attribute>
<attribute name="RefreshPeriod">10</attribute>
</mbean>
Then, I let my app check also this same properties file, no change made here.
I put this in my log4.properties file :
#Define root logger options
log4j.rootLogger=INFO, server
log4j.appender.status=org.apache.log4j.DailyRollingFileAppender
log4j.appender.status.File=${jboss.server.log.dir}/status.log
log4j.appender.status.DatePattern='.'yyyy-MM-dd
log4j.appender.status.layout=org.apache.log4j.PatternLayout
log4j.appender.status.layout.ConversionPattern=%d %-5p [%c] %m%n
log4j.appender.server=org.apache.log4j.DailyRollingFileAppender
log4j.appender.server.File=${jboss.server.log.dir}/server.log
log4j.appender.server.DatePattern='.'yyyy-MM-dd
log4j.appender.server.layout=org.apache.log4j.PatternLayout
log4j.appender.server.layout.ConversionPattern=%d %-5p [%c] %m%n
And that's it, it works great,I have both server messages and my app messages, without weird duplicate date, log level or anything.

Cannot Reach CDI Backing Bean With JSF 2.2 on WildFly 21

I have been following this tutorial to setup JSF on Eclipse version 2020-09 (4.17.0) with JAVA-14 and Maven on Wildfly-21.0 server on Windows 10. After completing the instructions on the page, I can browse to my index.xhtml page, but I cannot reach the backing bean when I submit the form. I get the following error instead:
[javax.enterprise.resource.webcontainer.jsf.context] (default task-1) javax.el.PropertyNotFoundException: /index.xhtml #14,61 value="#{bean.input}": Target Unreachable, identifier 'bean' resolved to null: javax.el.PropertyNotFoundException: /index.xhtml #14,61 value="#{bean.input}": Target Unreachable, identifier 'bean' resolved to null
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:64)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:71)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIInput.getConvertedValue(UIInput.java:1110)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIInput.validate(UIInput.java:1011)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIInput.executeValidate(UIInput.java:1322)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIInput.processValidators(UIInput.java:733)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIForm.processValidators(UIForm.java:229)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:608)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:159)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIComponent.visitTree(UIComponent.java:1456)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIForm.visitTree(UIForm.java:355)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIComponent.visitTree(UIComponent.java:1468)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIComponent.visitTree(UIComponent.java:1468)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:400)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:261)
at javax.faces.api#3.0.0.SP04//javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1308)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:53)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
at javax.faces.api#3.0.0.SP04//javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:707)
at javax.faces.api#3.0.0.SP04//javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at io.opentracing.contrib.opentracing-jaxrs2//io.opentracing.contrib.jaxrs2.server.SpanFinishingFilter.doFilter(SpanFinishingFilter.java:52)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.core#2.2.2.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.core#2.2.2.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.core#2.2.2.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.core#2.2.2.Final//io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.core#2.2.2.Final//io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.core#2.2.2.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.core#2.2.2.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.core#2.2.2.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at io.undertow.core#2.2.2.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
at org.wildfly.extension.undertow#21.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
at io.undertow.servlet#2.2.2.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
at io.undertow.core#2.2.2.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
at io.undertow.core#2.2.2.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:841)
at org.jboss.threads#2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads#2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads#2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads#2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at org.jboss.xnio#3.8.2.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'bean' resolved to null
at org.glassfish.jakarta.el#3.0.3.jbossorg-2//com.sun.el.parser.AstValue.getTarget(AstValue.java:148)
at org.glassfish.jakarta.el#3.0.3.jbossorg-2//com.sun.el.parser.AstValue.getType(AstValue.java:62)
at org.glassfish.jakarta.el#3.0.3.jbossorg-2//com.sun.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:160)
at org.jboss.weld.core#3.1.5.Final//org.jboss.weld.module.web.el.WeldValueExpression.getType(WeldValueExpression.java:93)
at org.jboss.weld.core#3.1.5.Final//org.jboss.weld.module.web.el.WeldValueExpression.getType(WeldValueExpression.java:93)
at com.sun.jsf-impl#2.3.14.SP01//com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:62)
... 70 more
In eclipse my project's properties, the "Project Facets" I can't set JavaServer Faces version to 2.3 because I get a "Cannot change version of project facet JavaServer Faces to 2.3". So I opted for version 2.2 instead. According to this stack overflow post, something may be wrong with my CDI implementation.
Any suggestion on how I can fix this issue and move forward?
Thanks in advance!
My POM file:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tanvir.project</groupId>
<artifactId>SudokuSolver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Sudoku Solver</name>
<description>Webapp for solving sudoku puzzles</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>9.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
My WEB-INF/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">
</beans>
My WEB-INF/faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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-facesconfig_2_2.xsd"
version="2.2">
<!-- JSF configuration here. -->
</faces-config>
My Backing Bean:
package tanvir.project.sudoku;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
#Named
#RequestScoped
public class Bean {
private String input;
private String output;
public void submit() {
output = "Hello World! You have typed: " + input;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
}
Finally, my xhtml file:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<h:head>
<title>Hello World</title>
</h:head>
<h:body>
<h1>Hello World</h1>
<h:form>
<h:outputLabel for="input" value="Input" />
<h:inputText id="input" value="#{bean.input}" />
<h:commandButton value="Submit" action="#{bean.submit}">
<f:ajax execute="#form" render=":output" />
</h:commandButton>
</h:form>
<h:outputText id="output" value="#{bean.output}" />
</h:body>
</html>
Insdead of using jakarta.jakartaee-api version 8.0.0 as mentioned in the tutorial, I used version 9.0.0. This required me to import jakarta.inject.Named insdead of javax.inject.Named in my Bean.java to use #Named annotation. The problem got fixed (can now refer to backing bean using EL statements) when I set jakarta.jakartaee-api version to 8.0.0 in the POM file.

RESTful web-service not found when I deploy app in eclipse

So, I have a Spring Maven web-app with a handful of RESTful web-services. For testing, this project is in Spring (4.1.4.RELEASE). I am using the latest STS (Spring-Eclipse) tool, and I am using Tomcat 8 for the server.
My UserController is designed as follows:
#Controller
#RequestMapping("/users")
public class UserController {
private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
#Autowired
private IUserService service;
#RequestMapping(value = "", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
ArrayList<UserEntity> getUserList()
{
System.out.println("UserController: getUserList: START");
ArrayList<UserEntity> userEntityList = (ArrayList) service.getAllUsers();
return userEntityList;
}
#RequestMapping(value = "/", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
ArrayList<UserEntity> getAllUsers()
{
System.out.println("UserController: getAllUsers: START");
ArrayList<UserEntity> userEntityList = (ArrayList) service.getAllUsers();
return userEntityList;
}
I have a test which runs when I build the app with maven, and this works great:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations =
{ "classpath:/spring/angular-context.xml", "file:src/main/webapp/WEB-INF/springmvc-servlet.xml" })
#Transactional
public class BaseControllerTests extends TestCase {
#Test
public void testMockGetUserList1() throws Exception
{
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/users/");
this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk());
}
#Test
public void testMockGetUserList2() throws Exception
{
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/users");
this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk());
}
}
The web-xml file looks like:
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/angular-context.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:/logging/log4j-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Servlets -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jUnitHostImpl</servlet-name>
<servlet-class>com.google.gwt.junit.server.JUnitHostImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jUnitHostImpl</servlet-name>
<url-pattern>/SoccerApp/junithost/*</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
And the angular-context.xml file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.tomholmes.angularjs.phonebook" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/phonebook</value>
</property>
<property name="username">
<value>myusername</value>
</property>
<property name="password">
<value>mypassword</value>
</property>
</bean>
<!-- JNDI DataSource for Java EE environments -->
<!-- <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/MyDatabase"/> -->
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="com.tomholmes.angularjs.phonebook.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
</props>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.tomholmes.net" />
<property name="port" value="587" />
<property name="username" value="myusername" />
<property name="password" value="mypassword" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
<!--
<bean id="sendMailService" class="com.tomholmes.angularjs.phonebook.shared.util.SendEmailService">
<property name="mailSender" ref="mailSender" />
</bean>
-->
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
So, this project compiles under maven just fine. Under eclipse (STS) with the Tomcat 8 engine, it runs fine, and I can go to my app:
http://localhost:8080/angularjs-phone-book/
and I can see the index.html just fine, so I know the app is out there.
If I go to:
http://localhost:8080/angularjs-phone-book/users
http://localhost:8080/angularjs-phone-book/users/
http://localhost:8080/angularjs-phone-book/rest/users
http://localhost:8080/angularjs-phone-book/rest/users/
Nothing works, and I get a 404 error that this web-service is not found.
But like I said, I know the test works, but I can't see what the exact URL has to be to get there.
I tried deploying the WAR on Tomcat 8 directly, but this web-app won't even start there, supposedly because of logging problems.
If I can provide any more information, please let me know. Any help in finding this would be great. Ultimately I want to have an AngularJS UI on the front-end tied to web-services, and I have to get the web-services working first.
Thanks!
You probably miss the Spring config reference from your web.xml. The unit test runs because you give the reference to the XML directly there, but not in web.xml, so Spring will not scan your controller for annotations.
Use an <init-param> inside <servlet>!
And the correct URL will be the last one, that is, with .../rest/users/, and .../rest/users is also allowed by the help of the browser, I guess.

GWT remote logging going to System.out instead of log file

I have setup gwt remote logging based on the gwt documentation, however my logs are going to System.out instead of being written to a log file.
My gwt module looks like:
<module rename-to='ezdappserver'>
<inherits name="com.google.gwt.logging.Logging"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<set-property name="gwt.logging.logLevel" value="FINEST"/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<set-property name="gwt.logging.consoleHandler" value="ENABLED" />
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
</module>
My servlet definition is setup like:
<servlet>
<servlet-name>remoteLogging</servlet-name>
<servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>remoteLogging</servlet-name>
<url-pattern>/ezdappserver/remote_logging</url-pattern>
</servlet-mapping>
When an error is logged I see output in my console like so:
Mar 26, 2014 2:10:36 PM com.google.gwt.logging.server.RemoteLoggingServiceUtil logOnServer
SEVERE: Exception caught: (NotFoundError)
....Rest of error....
I was expecting this output to be written to a log file somewhere in my war. Also, I would really like to be able to specify where this file is located, however I haven't been able to find any documentation on that either.
Any help would be much appreciated.
NOTE: I am not running this through dev mode, this is with compiled code.
Thanks!
Try below options also in gwt.xml based on your requirement:
<!-- This handler sends log messages to the server, where they will be logged using the server side logging mechanism. -->
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<!-- Logs by calling method GWT.log. These messages can only be seen in Development Mode in the DevMode window. -->
<set-property name="gwt.logging.developmentModeHandler" value="ENABLED" />
<!-- These messages can only be seen in Development Mode in the DevMode window. -->
<set-property name="gwt.logging.systemHandler" value="ENABLED" />
<!-- Logs to the popup which resides in the upper left hand corner of application when this handler is enabled. -->
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<!-- Logs to the javascript console, which is used by Firebug Lite (for IE), Safari and Chrome. -->
<set-property name="gwt.logging.consoleHandler" value="DISABLED"/>
<!-- Logs to the firebug console. -->
<set-property name="gwt.logging.firebugHandler" value="DISABLED" />
If above configuration are still not working for you then try below code along with above configuration.
Add log4j.xml file to define the log file location with log level
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="DT=> %d [%.4t] %-5p %c{1} - %m%n" />
</layout>
</appender>
<appender name="SERVER_FILE_LOG" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/logs/DataTools_Server.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5MB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%.4t] %-5p [%c] %m%n" />
</layout>
</appender>
<appender name="CLIENT_FILE_LOG" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/logs/DataTools_Client.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5MB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%.4t] %-5p %m%n" />
</layout>
</appender>
<category name="com.x.y.server">
<priority value="DEBUG" />
<appender-ref ref="SERVER_FILE_LOG" />
<appender-ref ref="STDOUT" />
</category>
<category name="gwtRemoteLogging">
<priority value="ERROR" />
<appender-ref ref="CLIENT_FILE_LOG" />
</category>
<root>
<priority value ="ERROR" />
<appender-ref ref="SERVER_FILE_LOG" />
</root>
</log4j:configuration>
Define you own logging servlet by implementing RemoteLoggingService
import java.util.logging.Level;
import java.util.logging.LogRecord;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import com.google.gwt.logging.server.StackTraceDeobfuscator;
import com.google.gwt.logging.shared.RemoteLoggingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.apache.log4j.Logger;
/**
* The Class GwtRemoteLogging.
*/
#SuppressWarnings("serial")
public class GwtRemoteLogging extends RemoteServiceServlet implements RemoteLoggingService {
/** The Constant logger. */
private StackTraceDeobfuscator deobfuscator = null;
private final static Logger logger = Logger.getLogger("gwtRemoteLogging");
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
/**
* Logs a Log Record which has been serialized using GWT RPC on the server.
*
* #return either an error message, or null if logging is successful.
*/
public final String logOnServer(LogRecord lr) {
try {
if (lr.getLevel().equals(Level.SEVERE)) {
logger.error(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.INFO)) {
logger.info(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.WARNING)) {
logger.warn(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.FINE)) {
logger.debug(lr.getMessage(),lr.getThrown());
} else {
logger.trace(lr.getMessage(),lr.getThrown());
}
} catch (Exception e) {
logger.error("Remote logging failed", e);
return "Remote logging failed, check stack trace for details.";
}
return null;
}
/**
* By default, this service does not do any deobfuscation. In order to do server side
* deobfuscation, you must copy the symbolMaps files to a directory visible to the server and
* set the directory using this method.
*
* #param symbolMapsDir
*/
public void setSymbolMapsDirectory(String symbolMapsDir) {
if (deobfuscator == null) {
deobfuscator = new StackTraceDeobfuscator(symbolMapsDir);
} else {
deobfuscator.setSymbolMapsDirectory(symbolMapsDir);
}
}
}
web.xml
<servlet>
<servlet-name>remoteLogServlet</servlet-name>
<servlet-class>com.x.y.server.servlet.GwtRemoteLogging</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>remoteLogServlet</servlet-name>
<url-pattern>/ezdappserver/remote_logging</url-pattern>
</servlet-mapping>
The RemoteServiceServlet uses java.util.logging to log, and by default it logs to the console (System.err, not System.out BTW).
If you want to log to a file, then you have to configure java.util.logging; either editing your global lib/logging.properties (not recommended), using your own config file that you pass to the JVM using the java.util.logging.config.file system property, or programmatically.
Depending on your servlet container, it can be configured by different means. For instance, Tomcat will read a logging.properties file in your WEB-INF/classes: http://tomcat.apache.org/tomcat-7.0-doc/logging.html#Using_java.util.logging_(default)

Spring #Autowired annotation giving null for dozer mapping

Here is my class I am trying to use this annotation and I am getting null for dozerBeanMapper. I also get null for other beans I am trying to use like Jaxb2Mapper, etc
#Service("Transformer")
#Scope("prototype")
public class Transformer {
#Autowired
private Mapper dozerBeanMapper;
public Object testMethod(Object wlpData) throws TransformerException {
MbrReq destObject = null;
destObject = dozerBeanMapper.map(request, MbrReq.class);
return destObject;
}
Here is my configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<sws:annotation-driven />
<context:component-scan base-package="com.xxxxx.xxxx.srvc.membership,com.xxxxx.xxxx.interact.membership.request,com.xxxxx.membership.ws,com.xxxxxx.srvc.membership.generated,com.xxxxx.xxxx.service.transform" />
<!-- WSDL Exposed as memberService -->
<bean id="searchMemDemographics" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
<constructor-arg value="/WEB-INF/schema/MemSvc_Binding_HTTP_V0100.wsdl"/>
</bean>
<bean class="org.dozer.spring.DozerBeanMapperFactoryBean">
<property name="mappingFiles">
<list>
<value>classpath:mapping/dozer-global-configuration.xml</value>
<value>classpath:mapping/dozer-bean-mappings.xml</value>
</list>
</property>
</bean>
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.xxxxx.srvc.membership" />
<oxm:jaxb2-marshaller id="reqMarshaller" contextPath="com.xxxxxx.membership.request" />
<oxm:jaxb2-marshaller id="respMarshaller" contextPath="com.xxxxxx.membership.response" />
In web.xml I have this
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/membershipApplicationContext.xml
</param-value>
</context-param>
Anything else I am missing ?
Try adding an id to the bean.
<bean id="dozerBeanMapper" class="org.dozer.spring.DozerBeanMapperFactoryBean">