0

I am trying to get the server URL (eg. http://www.mywebapp.com/myapp) from the ServletContext when the application starts up, I am doing this by invoking a bean method on startup (using @Startup) and getting the servlet context,

@Startup
@Name("startupActions")
@Scope(ScopeType.APPLICATION)
public class StartupActionsBean implements StartupActions,
Serializable {

@Logger private Log log;

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Create
@Override
public void create(){
    ServletContext sc = org.jboss.seam.contexts.ServletLifecycle.getServletContext();
    String context = sc.getContextPath();
    String serverInfo = sc.getServerInfo();
    log.debug("__________________START__________________");
    log.debug("Context Path: "+context);
    log.debug("Server Info: "+serverInfo);
}

// Cleanup methods
@Remove
@BypassInterceptors
@Override
public void cleanUp(){}
}

This work ok, however the ServletContext path is blank, see console output below..

18:52:54,165 DEBUG [uk.co.app.actions.startup.StartupActionsBean] __________________START__________________
18:52:54,165 DEBUG [uk.co.app.actions.startup.StartupActionsBean] Context Path: 
18:52:54,165 DEBUG [uk.co.app.actions.startup.StartupActionsBean] Server Info: JBoss Web/3.0.0-CR1

Does anyone know how to get the contextpath through this, or other means?

ps. using SEAM 2.2.2, Jboss AS6 Final, Richfaces 3.3.3

athspk
  • 6,722
  • 7
  • 37
  • 51
DaveB
  • 2,953
  • 7
  • 38
  • 60

2 Answers2

1

Don't use @Startup, your component startup code gets called before contexts are fully setup and some other factories could not be yet initialized.

Observe the org.jboss.seam.postInitialization event and use the same ServletLifecycle.getCurrentServletContext() to get hold of the data needed. A quick example:

@Name("contextPath")
public class ContextPathInit implements Serializable {
    private String contextPath;

    @Observer("org.jboss.seam.postInitialization")
    public void init() {
        contextPath = ServletLifecycle.getCurrentServletContext().getContextPath();
    }
}
EmirCalabuch
  • 4,756
  • 1
  • 25
  • 20
  • thanks EmirCalabuch, I tested the above, and it still just outputting an empty String?, in fact, it only seems to get invoked when the server it hot-deployed, not from a cold start? – DaveB Sep 25 '12 at 14:11
  • An empty string in `getContextPath()` is ok only if your application is in the root context. The observer method should be invoked always at the end of the startup process. If it doesn't, check that the component class is not in the `src/hot` folder. Also, try using the `create=true` option in the `@Observer` annotation. – EmirCalabuch Sep 25 '12 at 16:05
  • ah ok, but I am trying to get the domain of the server, eg. http://myapp.com....sorry if that wasnt clear. Would there be a better way to do this? – DaveB Sep 26 '12 at 10:51
  • Outside a request, it depends on your server. On JBoss you can call an MBean to get the bind address (not necessarily the DNS name, depends on the bind parameter of the server). See [this code](http://pastebin.com/c0UfyLFK). If you're behind a reverse proxy, then that's a no, you will only see the internal address. Your best bet I think is to either create a filter to intercept the first JSF call and take the URL from it or (KISS principle does wonders) simply make the URL a configurable parameter. – EmirCalabuch Sep 26 '12 at 19:53
  • Thanks again, I tried the MBean code but I could not locate the MBeanServerInvocationHandler library?....As you say KISS looks like the best solution, I am currently storing it as a parameter as you suggest, the purpose is to auto-detect if the server is live or dev and one day I will forget to change it manually! – DaveB Sep 27 '12 at 14:34
  • If your scope is that, one simple thing is to pass the URL parameter from the command line string that starts jboss. See [this answer](http://stackoverflow.com/a/10929601/1417546), but simply put you can use the command line `run.sh -Dorg.jboss.seam.properties.config.url="http://www.mywebapp.com" -c default` and seam will automatically put the value passed into the `url` property of a component named `config` (the component and property names are up to you). This way you can have the launch script of the live setup to be different from that of the dev setup. – EmirCalabuch Sep 27 '12 at 14:53
0

Have you tried getting it from ExternalContext using the getContextName method?

FacesContext.getCurrentInstance().getExternalContext().getContextName()
munyengm
  • 15,029
  • 4
  • 24
  • 34
  • I believe this will only get invoked from an http request (user loading webpage), I want to get it when the application starts – DaveB Sep 23 '12 at 21:04