16

All,

I have 2 web applications, Web1 and Web2, deployed on my tomcat server. I want classes in Web1 to call methods on classes in Web2. One way to do this is using webservice. Is there any other way similar to calling a method on class on same web application ?.

Thanks.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Gaurav
  • 1,549
  • 2
  • 15
  • 31
  • you do have to expose some service/interface. you can also use JMX/EJB/JNDI then. ofc, webservice will work even if you move the applications out of the process (i.e. 2 different web servers) but it always has to marshal/unmarshal the calls. – bestsss Jan 20 '12 at 09:08
  • @bestss That is the reason I don't want to use webservice. Don't want to use EJB/JNDI either. Can try JMX unless I find other better way. – Gaurav Jan 20 '12 at 09:10

5 Answers5

11

Yes. It is possible. It tried for same servlet container by using getServletContext().getContext() method.

First you need to make changes in below file

(Windows) C:\Program Files\Apache Software Foundation\Tomcat 7.0\conf\context.xml Set value of crossContext to true.

context.xml

<Context crossContext="true">

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <!-- 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>

Please note that crossContext="true".

Suppose you have two web applications with name InterServletComm1 and InterServletComm2 having servlets Servlet1 and Servlet1 in each web application respectively. Then the code in each servlets goes as follows:

Servlet1.java

package interServletComm1;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Servlet1
 */
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlet1() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();

        request.setAttribute("name", "WebApp1");
        ServletContext context = getServletContext().getContext("/InterServletComm2");
        RequestDispatcher rd = context.getRequestDispatcher("/Servlet2");
        rd.forward(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

Servlet2.java

package interServletComm2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Servlet2
 */
@WebServlet("/Servlet2")
public class Servlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlet2() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();
        String name = (String) request.getAttribute("name");
        pw.println("This is web application 2.");
        pw.println("<br>The value received from web application one is: " + name);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

Above code sends attribute name from InterServletComm1 and it is received in InterServletComm2. Please let me know if this answer is not clear.

Abhijeet Ashok Muneshwar
  • 2,480
  • 2
  • 31
  • 32
5

Just searched around some articles and the above scenario is certainly possible using CrossContext switching in Tomcat.

Set the following element in context.xml in <Context crossContext="true">

And then getServletContext().getContext("/Web2");.

Haven't tried yet, though.

Gaurav
  • 1,549
  • 2
  • 15
  • 31
  • 1
    yes, you can use cross context and dispatch (and it works) but then you'd be better off just having one web-app. You can uses classes directly from "the other" wen-app, though. – bestsss Jan 20 '12 at 09:40
  • @bestss i dont think you can directly use the classes of other web application. Both the classloaders will be different. – Ramesh PVK Jan 21 '12 at 06:02
  • @RameshPVK, absolutely, now reading the comment my fingers were too lazy - it was meant "cannot", i.e. in the contrast of dispatching. To use the classes they have to come from a common classloader but that's an entirely different story. – bestsss Jan 21 '12 at 13:56
2

Yes you can do it using javax.servlet.ServletContext and javax.servlet.RequestDispatcher API's. Here it is how it can be done from Web1:

ServletContext otherContext = servletContext.getContex("/Web2");
RequestDispatcher dispathcer = otherContext.getRequestDispatcher("/a/b.jsp");

dispatcher.forward(request, response);
//or
dispatcher.include(request, response);
Ramesh PVK
  • 15,200
  • 2
  • 46
  • 50
1

Package the classes you want to share between web applications into a separate jar. Put them under common/lib so that the common classloader will load the classes and would be available to both web applications. Then expose the instance in web2 using jndi, look up them from web1 and invoke the methods.

Bibin
  • 434
  • 2
  • 5
  • 20
  • 1
    Or simpler - no need for jndi, just have singleton in the common code, register the reference to the class instance you need to call on startup and get it from the other application. But beware that all the code you invoke from one webapp needs to be loaded by the same (common) classloader, which might force you to put more libraries in common/lib (or just lib since Tomcat 6). – Pavel Jun 06 '13 at 08:38
0

Pretty much it is not that simple. You can share and import classes from your app1 into app2, but maybe they're all linked with other classes. So the idea is not so good except of small services like beans which are used to make calculations for example. There is a reason ppl are using web services so much ;).