Where to start with a webapp that is not really a webapp

Discussion in 'Java' started by Andrew, Jun 26, 2009.

  1. Andrew

    Andrew Guest

    I have an app that is currently a Junit test but I want to convert it
    to a program that will run 24x7, i.e. a server. The dev env that I am
    in means the app uses many, many 3rd party jars. Loads of them. We
    also use several frameworks including spring and hibernate. There are
    many properties and beans that form part of our lengthly
    configuration. I have pointed out that ideally this app would be a
    standalone server. In the past I designed such apps with a main
    entrypoint and wrote a little shellscript to kick them off using the
    java VM with appropriate CLASSPATH settings. However, I have been
    asked to make it a webapp. I am looking for help.

    There are certain advantages to it being a webapp. Deployment is a
    snap, the jar issue is neatly taken care of and I don't need to write
    a shellscript either since tomcat will run the app for me. But the
    question is "how?". I haven't been doing java very long and working in
    webspace is very new to me. My server actually has nothing to do with
    the web, the webapp route is purely to simplify deployment and the
    general runtime env.

    The only other webapps I have seen are either using spring MVC or are
    a bean that listens to a JMS queue for ever. I can see how these work.
    In the first case tomcat starts the app in response to a URL pattern
    match and the entrypoint is the http request for the matching URL. In
    the second case the bean is a singleton and starts when tomcat starts.
    Since it listens to the JMS queue immediately and never shuts down
    there is no problem. My app does not fit into either of these
    categories. So what kind of entrypoint would I have? Obviously not a
    URL-related one. Does that mean it would have to be done as a
    singleton referred to in the bean configuration?

    Regards,

    Andrew Marlow
     
    Andrew, Jun 26, 2009
    #1
    1. Advertising

  2. "Andrew" <> wrote in message
    news:
    > I have an app that is currently a Junit test but I want
    > to convert it to a program that will run 24x7, i.e. a
    > server. The dev env that I am in means the app uses many,
    > many 3rd party jars. Loads of them. We also use several
    > frameworks including spring and hibernate. There are many
    > properties and beans that form part of our lengthly
    > configuration. I have pointed out that ideally this app
    > would be a standalone server. In the past I designed such
    > apps with a main entrypoint and wrote a little
    > shellscript to kick them off using the java VM with
    > appropriate CLASSPATH settings. However, I have been
    > asked to make it a webapp. I am looking for help.
    >
    > There are certain advantages to it being a webapp.
    > Deployment is a snap, the jar issue is neatly taken care
    > of and I don't need to write a shellscript either since
    > tomcat will run the app for me. But the question is
    > "how?". I haven't been doing java very long and working
    > in webspace is very new to me. My server actually has
    > nothing to do with the web, the webapp route is purely to
    > simplify deployment and the general runtime env.
    >
    > The only other webapps I have seen are either using
    > spring MVC or are a bean that listens to a JMS queue for
    > ever. I can see how these work. In the first case tomcat
    > starts the app in response to a URL pattern match and the
    > entrypoint is the http request for the matching URL. In
    > the second case the bean is a singleton and starts when
    > tomcat starts. Since it listens to the JMS queue
    > immediately and never shuts down there is no problem. My
    > app does not fit into either of these categories. So what
    > kind of entrypoint would I have? Obviously not a
    > URL-related one. Does that mean it would have to be done
    > as a singleton referred to in the bean configuration?


    If it does not have much web style services, I might write it into a
    HttpServlet, configuring it to load on startup. A servlet does not have to
    serve HTTP requests, but it might, along the other stuff it does.

    That might require own Threads, which are considered bad juju with J2EE
    containers, but doable.
     
    Donkey Hottie, Jun 26, 2009
    #2
    1. Advertising

  3. Andrew

    Lew Guest

    Andrew wrote:
    > standalone server. In the past I designed such apps with a main
    > entrypoint and wrote a little shellscript to kick them off using the
    > java VM with appropriate CLASSPATH settings.


    This doesn't answer your question, but there's a better way to deploy a
    standalone app, that is, as an executable JAR.

    You put the classpath in the JAR manifest and deliver the related libraries in
    a subdirectory (e.g., ./ or lib/) of the JAR deployment directory, then
    execute the JAR with "java -jar" (which ignores other classpath settings). No
    need for a shell script.

    --
    Lew
     
    Lew, Jun 26, 2009
    #3
  4. In article
    <>,
    Andrew <> wrote:

    > I have an app that is currently a Junit test but I want to convert it
    > to a program that will run 24x7, i.e. a server.


    If your test is simple and you just want to see the result:

    <code>
    import java.io.*;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    /** @author John B. Matthews */

    public class Test extends HttpServlet {

    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Exec";
    out.println("<html>");
    out.println("<head>");
    out.println("<title>" + title + "</title>");
    out.println("</head>");
    out.println("<body bgcolor=\"white\">");
    out.println("<h2>" + title + ": " + new Date() + "</h2>");
    doExec("java org.junit.runner.JUnitCore yourTest", out);
    out.println("</body>");
    out.println("</html>");
    }

    private void doExec(String cmd, PrintWriter out) {
    String s;
    try {
    Process p = Runtime.getRuntime().exec(cmd);
    // read from the process's stdout
    BufferedReader stdout = new BufferedReader (
    new InputStreamReader(p.getInputStream()));
    while ((s = stdout.readLine()) != null) {
    out.println(s + "<br>");
    }
    // read from the process's stderr
    BufferedReader stderr = new BufferedReader (
    new InputStreamReader(p.getErrorStream()));
    while ((s = stderr.readLine()) != null) {
    out.println(s + "<br>");
    }
    p.getInputStream().close();
    p.getOutputStream().close();
    p.getErrorStream().close();
    out.println("Exit value: " + p.waitFor() + "<br>");
    }
    catch (Exception e) {
    e.printStackTrace(out);
    }
    }
    }
    </code>

    Not tested; assumes correct classpath; meta refresh optional.

    [...]

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
     
    John B. Matthews, Jun 26, 2009
    #4
  5. Andrew

    Tom Anderson Guest

    On Fri, 26 Jun 2009, Andrew wrote:

    > I have an app that is currently a Junit test but I want to convert it
    > to a program that will run 24x7, i.e. a server. The dev env that I am
    > in means the app uses many, many 3rd party jars. Loads of them. We
    > also use several frameworks including spring and hibernate. There are
    > many properties and beans that form part of our lengthly
    > configuration. I have pointed out that ideally this app would be a
    > standalone server. In the past I designed such apps with a main
    > entrypoint and wrote a little shellscript to kick them off using the
    > java VM with appropriate CLASSPATH settings. However, I have been
    > asked to make it a webapp. I am looking for help.
    >
    > There are certain advantages to it being a webapp. Deployment is a
    > snap, the jar issue is neatly taken care of and I don't need to write
    > a shellscript either since tomcat will run the app for me. But the
    > question is "how?". I haven't been doing java very long and working in
    > webspace is very new to me. My server actually has nothing to do with
    > the web, the webapp route is purely to simplify deployment and the
    > general runtime env.
    >
    > The only other webapps I have seen are either using spring MVC or are
    > a bean that listens to a JMS queue for ever. I can see how these work.
    > In the first case tomcat starts the app in response to a URL pattern
    > match and the entrypoint is the http request for the matching URL. In
    > the second case the bean is a singleton and starts when tomcat starts.
    > Since it listens to the JMS queue immediately and never shuts down
    > there is no problem. My app does not fit into either of these
    > categories. So what kind of entrypoint would I have? Obviously not a
    > URL-related one. Does that mean it would have to be done as a
    > singleton referred to in the bean configuration?


    Your basic problem is that your app is completely unsuited to being a web
    app. The fundamental nature of web components is that they sit there and
    respond to web requests. A message-driven bean is similar, but it responds
    to JMS messages. Web services respond to SOAP calls. EJBs respond to RMI
    calls. Your app doesn't do any responding.

    I think, in fact, that there's a mistake in your very first sentence -
    needing to run all the time doesn't make it a server. It might make it a
    daemon, but it's not serving anyone, so it's not a server. All the J2EE
    infrastructure is about serving, so it's not really right for you. I think
    the original idea of a standalone app is the right one.

    However, it sounds like the need to make it a web app is external - it's
    not a design decision, it's a requirement. In which case, a web app it
    must be. And since you're talking about MDBs, i assume that by "webapp"
    you actually mean "J2EE component".

    In which case, the problem is finding something to respond to. My
    suggestion would be timer events. See:

    http://java.sun.com/javaee/5/docs/tutorial/backup/update3/doc/Session4.html

    You can create a recurring timer with:

    long intervalInMilliseconds;
    TimerService ts;
    ts.createTimer(0L, intervalInMilliseconds, null);

    Annotate your main method (IYSWIM) with @Timeout. Put the timer creation
    in a method annotated with @PostCreate. Then, as soon as the bean gets
    loaded, it will go into an infinite loop doing whatever it is it needs to
    do.

    The only problem then is causing it to be loaded. I don't think the
    container will create an instance on deployment - i think the bean has to
    be referenced first. I'm not aware of anything you can write in the
    deployment descriptor which changes this, but i'm pretty ignorant when it
    comes to EJB, really. It would be simple enough to create a client which
    connects to the EJB and pokes it over RMI to get it loaded. I don't think
    it even has to do RMI, actually - i suspect a JNDI lookup will be enough.
    You'd then need to run the client after deploying the component.

    Alternatively, rather than creating the timer in a @PostCreate method, put
    a start() method on the bean, and do it in there. Have the service-starter
    client call that method. You could then add a stop() method which cancels
    the timer, in case you decide your loop shouldn't be infinite after all.
    You could even then add a status() method, which lets the client app check
    whether the component is working properly - that triad of operations is a
    pretty common in service-control tools. You often see a restart() too.

    A related approach would be to look at something like Quartz, which is a
    more sophisticated scheduling service (and funnily enough, which pretends
    to be, or perhaps even is, a JMS source, so your job would be an MDB,
    getting a message whenever it was time to run). With that, there are ways
    of configuring scheduled jobs which wouldn't require you to explicitly
    start the service - it would be run automatically as long as it was on the
    schedule. JBoss comes with Quartz built in; i don't know about other app
    servers.

    tom

    --
    .... the gripping first chapter, which literally grips you because it's
    printed on a large clamp.
     
    Tom Anderson, Jun 26, 2009
    #5
  6. Tom Anderson wrote:

    > The only problem then is causing it to be loaded. I don't think the
    > container will create an instance on deployment - i think the bean has
    > to be referenced first. I'm not aware of anything you can write in the
    > deployment descriptor which changes this, but i'm pretty ignorant when
    > it comes to EJB, really. It would be simple enough to create a client
    > which connects to the EJB and pokes it over RMI to get it loaded. I
    > don't think it even has to do RMI, actually - i suspect a JNDI lookup
    > will be enough. You'd then need to run the client after deploying the
    > component.


    A servlet can be configured to load on startup in web.xml, and in the
    servlet's init method I could call a 'start' method of a stateless
    session bean. This start method can get a TimerService instance using
    its context.

    How can I use the J2EE Timer Service API in the Servlet startup code?
    http://stackoverflow.com/questions/1024081/

    I have not done it in the actual test or production environment but I
    think that the benefit of moving Java services to a J2EE container is
    the availability of common services like JMS and datasources, and also
    administration.



    --
    Michael Justin
    SCJP, SCJA
    betasoft - Software for Delphiâ„¢ and for the Javaâ„¢ platform
    http://www.mikejustin.com - http://www.betabeans.de
     
    Michael Justin, Jun 28, 2009
    #6
  7. Andrew

    Andrew Guest

    On 26 June, 14:54, Lew <> wrote:
    > Andrew wrote:
    > > standalone server. In the past I designed such apps with a main
    > > entrypoint and wrote a little shellscript to kick them off using the
    > > java VM with appropriate CLASSPATH settings.

    >
    > This doesn't answer your question, but there's a better way to deploy a
    > standalone app, that is, as an executable JAR.
    >
    > You put the classpath in the JAR manifest and deliver the related libraries in
    > a subdirectory (e.g., ./ or lib/) of the JAR deployment directory, then
    > execute the JAR with "java -jar" (which ignores other classpath settings)..  No
    > need for a shell script.


    Many thanks for this tip. I think that this is just what I need in
    this case. We also have other apps that IMO should be deployed in this
    way.
     
    Andrew, Jun 28, 2009
    #7
  8. Andrew

    Andrew Guest

    On 26 June, 22:15, Tom Anderson <> wrote:
    > On Fri, 26 Jun 2009, Andrew wrote:
    > > I have an app that is currently a Junit test but I want to convert it
    > > to a program that will run 24x7, i.e. a server.


    > Your basic problem is that your app is completely unsuited to being a web
    > app. The fundamental nature of web components is that they sit there and
    > respond to web requests. A message-driven bean is similar, but it responds
    > to JMS messages. Web services respond to SOAP calls. EJBs respond to RMI
    > calls. Your app doesn't do any responding.


    Yes.

    > I think, in fact, that there's a mistake in your very first sentence -
    > needing to run all the time doesn't make it a server. It might make it a
    > daemon, but it's not serving anyone, so it's not a server.


    Er, yes, you're right. <blush>

    > However, it sounds like the need to make it a web app is external - it's
    > not a design decision, it's a requirement.


    Right again!

    > In which case, a web app it
    > must be. And since you're talking about MDBs, i assume that by "webapp"
    > you actually mean "J2EE component".
    >
    > In which case, the problem is finding something to respond to.


    Yes, and this a big unknown. AFAIK there are no plans for any other
    process to call us as a web service.

    > My suggestion would be timer events. See:
    >
    > http://java.sun.com/javaee/5/docs/tutorial/backup/update3/doc/Session...
    >
    > You can create a recurring timer with:
    >
    > long intervalInMilliseconds;
    > TimerService ts;
    > ts.createTimer(0L, intervalInMilliseconds, null);
    >
    > Annotate your main method (IYSWIM) with @Timeout. Put the timer creation
    > in a method annotated with @PostCreate. Then, as soon as the bean gets
    > loaded, it will go into an infinite loop doing whatever it is it needs to
    > do.


    This sounds very promising. Many thanks for your help :)

    >
    > The only problem then is causing it to be loaded. I don't think the
    > container will create an instance on deployment - i think the bean has to
    > be referenced first. I'm not aware of anything you can write in the
    > deployment descriptor which changes this, but i'm pretty ignorant when it
    > comes to EJB, really. It would be simple enough to create a client which
    > connects to the EJB and pokes it over RMI to get it loaded. I don't think
    > it even has to do RMI, actually - i suspect a JNDI lookup will be enough.
    > You'd then need to run the client after deploying the component.


    I cannot see anyone doing this. They talk of web services but really,
    I think what they mean is a webapp that will visit a particular URL to
    available themselves of some 'service' or other. So far these have
    been mainly admin screens. That's not really the case for us.


    >
    > Alternatively, rather than creating the timer in a @PostCreate method, put
    > a start() method on the bean, and do it in there. Have the service-starter
    > client call that method. You could then add a stop() method which cancels
    > the timer, in case you decide your loop shouldn't be infinite after all.
    > You could even then add a status() method, which lets the client app check
    > whether the component is working properly - that triad of operations is a
    > pretty common in service-control tools. You often see a restart() too.


    This sounds to me like what we should do until they make their minds
    up.

    >
    > A related approach would be to look at something like Quartz, which is a
    > more sophisticated scheduling service


    IMO that would be overkill. There are quite enough new technologies
    and third party jars in the system without us adding to the problem.

    Thanks again for your suggestions.

    -Andrew Marlow
     
    Andrew, Jun 28, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Amir
    Replies:
    3
    Views:
    621
  2. Replies:
    3
    Views:
    575
    avnrao
    May 21, 2004
  3. Ray5531
    Replies:
    2
    Views:
    519
  4. Replies:
    6
    Views:
    456
    S. Justin Gengo [MCP]
    Feb 10, 2006
  5. Just D.
    Replies:
    5
    Views:
    478
    Just D.
    Jan 15, 2007
Loading...

Share This Page