1

I have upgraded my Servlet from 2.4 to 3.0 and deployed my application on Websphere 8.5.5.8. Application Server starts properly. When I try to access my home.jsp page in browser it throws:

Controller Main Error OG1000SRVE0190E: File not found: /servlet/com.platform7.affina.operations.servlet.ValidateLoginUser

When I try to debug, code hits my Main Controller Servlet (which is in same package) but inside Controller servlet class I am calling:

this.getServletContext().getRequestDispatcher("Servlet/com.platform7.affina.operations.servlet.ValidateLoginUser").forward(request, response);

Which throws:

FileNotFoundException for Servlet/com.platform7.affina.operations.servlet.ValidateLoginUser.

But ValidateLoginUser is in the same package and classes folder location!

Folder structure:

\NEED4SPEEDCell02\operations_1.ear\OperationsWeb.war\WEB-INF\classes\com\platform7\affina\operations\servlet

ControllerMain.class and ValidateLoginUser.class are in same servlet package.

my Web.xml file:

<servlet>
    <servlet-name>servletMain</servlet-name>
    <servlet-class>com.platform7.affina.operations.servlet.ControllerMain</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>servletMain</servlet-name>
    <url-pattern>/controllerMain</url-pattern>
</servlet-mapping>

So when I access my URL: it hits ControllerMain.class but inside this class I am calling another servlet which is not part of web.xml but is located in same package of ControllerMain.class.

When I print realpath: this.getServletContext().getRealPath("/"));

I get:

C:\WebSphere858\AppServer\profiles\AppSrv01\installedApps\NEED4SPEEDCell02\operations_1.ear\OperationsWeb.war

I tried using getNamedDispatcher(..) too but throws: null.

Same code works fine on Websphere 7 and even works on Websphere 8.5.5.5

Florian Lemaitre
  • 5,905
  • 2
  • 21
  • 44
Tej
  • 39
  • 6

3 Answers3

2

Due to security reasons the default setting for com.ibm.ws.webcontainer.disallowServeServletsByClassname property has been changed.

Please Note:This APAR has changed the default value of the WebContainer custom property com.ibm.ws.webcontainer.disallowServeServletsByClassname from false to true so that no security threat could occur. Prior to this change, it was up to the developer to remember to change the custom property to true before deploying into production.

Property Name: com.ibm.ws.webcontainer.disallowServeServletsByClassname Description: If set to true, disallows the use of serveServletsByClassnameEnabled at the application server level, overriding any setting of serveServletsByClassnameEnabled at the application level. This property affects all applications. Values: true(default)/false

You will need to add that custom property to the Web Container and set it to false for serving servlets by class name.

But as BalusC suggested, you should add your servlet to web.xml in the form:

<servlet>
    <servlet-name>servletMain</servlet-name>
    <servlet-class>com.platform7.affina.operations.servlet.ValidateLoginUser</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>servletMain</servlet-name>
    <url-pattern>/validateLoginUser</url-pattern>
</servlet-mapping>

and change that forward to:

this.getServletContext().getRequestDispatcher("/validateLoginUser").forward(request, response);

And do the same with your other class from the same package.

Gas
  • 17,601
  • 4
  • 46
  • 93
  • Brilliant Gas, Sorry for late reply as it took lot of deployment time after the changes you suggested. So thought of trying first before commenting. Many many thanks for your solution. It works combination of both the solutions, yours and BalusC. I have to change all my servlet calling pattern getServletContext().getRequestDispatcher("...") and web.xml accordingly. Many Thanks again. – Tej Feb 26 '16 at 08:17
  • Nice to heat that. If you add your servlet to `web.xml`, and change dispatcher to use mapping name, then you no longer need to set that property and to set `serveServletsByClassnameEnabled` in the `ibm-web-ext.xml`. – Gas Feb 26 '16 at 11:27
1

You seem to be relying on the legacy InvokerServlet which is known to have major security holes. This was deprecated in Tomcat 5 and clones (WebSphere 4) and removed in Tomcat 7 and clones (WebSphere 6).

You're not supposed to use it anymore. Just map the servlet on a normal URL pattern and invoke it. Assuming that the servlet is mapped on an URL pattern of /validateLoginUser via @WebServlet("/validateLoginUser") annotation on the servlet class, or via <url-pattern>/validateLoginUser</url-pattern> in web.xml mapping on the servlet, then you can get a request dispatcher on it as below:

request.getRequestDispatcher("/validateLoginUser");

Or, just refactor shared code to a plain Java class with a method and invoke it the usual Java way. It's these days kind of weird to have shared validation logic tight coupled in a servlet.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for your kind help Balusc. Problem is, my Company doesn't want to do major code change. Else I will preferably remove all these old code legacy pattern of web.xml and remove tight coupling and go ahead with annotations. We need to support websphere 8.5.5.8 which needs Servlet 3. Original code was return using Servlet 2.4 Same code works with Websphere 7 and even works on Websphere 8.5.5.5 but its started complaining with 8.5.5.8 :( – Tej Feb 25 '16 at 10:43
  • Thanks BalusC, you are right and your solution works too. – Tej Feb 26 '16 at 08:36
0

To make above upgrade working, I did few other changes as below for future references.

Mainly, I have to change binding files for websphere. Previously, I had two bindings ibm-web-bnd.xmi and ibm-web-ext.xmi

ibm-web-bnd.xmi

<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:com.ibm.ejs.models.base.bindings.webappbnd="webappbnd.xmi" xmi:id="WebAppBinding_1226331113121" virtualHostName="default_host">
  <webapp href="WEB-INF/web.xml#WebApp"/>
    <resRefBindings xmi:id="ResourceRefBinding_1226331113121" jndiName="AffinaDataSource_pma">
      <bindingResourceRef href="WEB-INF/web.xml#ResourceRef_AffinaDataSource_pma"/>
    </resRefBindings>
</com.ibm.ejs.models.base.bindings.webappbnd:WebAppBinding>

ibm-web-ext.xmi

<?xml version="1.0" encoding="UTF-8"?>
<com.ibm.ejs.models.base.extensions.webappext:WebAppExtension 
    xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" 
    xmlns:com.ibm.ejs.models.base.extensions.webappext="webappext.xmi" 
    xmi:id="WebAppExtension_1226331113121"
    serveServletsByClassnameEnabled="true">
  <webApp href="WEB-INF/web.xml#WebApp"/>
  <jspAttributes xmi:id="JSPAttribute_1226331113121" name="reloadEnabled" value="true"/>
  <jspAttributes xmi:id="JSPAttribute_1226331113122" name="reloadInterval" value="10"/>
</com.ibm.ejs.models.base.extensions.webappext:WebAppExtension>

So as per servlet3 and Websphere 8.5.5.8, I change to replace above two .xmi files with ibm-web-bnd.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd" version="1.0">

  <virtual-host name="default_host"/>
  <resource-ref name="AffinaDataSourceAlias_pma" binding-name="AffinaDataSource_pma"/>

</web-bnd>

and then while installing application on Websphere 8.5.5.8, it use to throw outofmemmory error, so to fix that I change below max memory parameter from 256m to 512m in wsadmin.bat

C:\WebSphere858\AppServer\bin\wsadmin.bat

set PERFJAVAOPTION=-Xms256m -Xmx512m -Xquickstart

Hope this helps.

Tej
  • 39
  • 6