2

I'm trying to get a list of all deployed applications, and specifically the name of the application mapped to tomcat root. I want to be able to do it during runtime, using a java agent that collects information on the tomcat server. I tried using this code sample:

private Iterable<String> collectAllDeployedApps() {
    try {
        final Set<String> result = new HashSet<>();
        final Set<ObjectName> instances = findServer()
                .queryNames(new ObjectName("Tomcat:j2eeType=WebModule,*"), null);
        for (ObjectName each : instances) {
            result.add(substringAfterLast(each.getKeyProperty("name"), "/")); //it will be in format like //localhost/appname 
        }
        return result;
    } catch (MalformedObjectNameException e) {
         //handle
    }
}

taken from a similar question but since I'm not logged into the manager app, I don't have the right permissions, so I get an empty list.

What I actually want - I have a java agent (based on aspectJ), and I'd like during runtime/deployment time etc. to be able to get the list of all deployed apps without actually logging in to the manager myself. How can I do this? I don't mind instrumenting tomcat's deployment code (which doesn't require any login from my side as I'm already instrumenting the code), but I'm not sure which function to instrument.

Thanks, Lin

Community
  • 1
  • 1
Lin
  • 2,445
  • 5
  • 27
  • 37
  • Why are you trying to circumvent container security? Why not just log into the manager programmatically? There must be an API for it. Are you seriously trying to get help hacking an application server here on SO? Please explain yourself before I consider helping you. – kriegaex Sep 18 '16 at 09:03
  • @kriegaex - it's an "add on" on an application, like a monitoring tool, I'm not trying to hack anything. The agent can access and see whatever is been done in the system, but it doesn't have the login info. It can access tomcat's startup code as well, and it's enough for me to instrument that code. I just cannot use the API because it requires the agent to login, and on the other hand I'm not sure what code in tomcat deploys the applications (which if instrumented in advance is good enough for me). – Lin Sep 18 '16 at 10:20
  • @kriegaex - the application is started with the agent (byte code instrumentation) – Lin Sep 18 '16 at 10:27
  • 1
    I have a partial solution - to get the name of the root application in tomcat I can use ServletContext.getRealPath(). This solves the root name. As for getting the list, it's something I can live without, so I can manage for now. It would still be nice to know in which code part tomcat deploys the application... – Lin Sep 20 '16 at 19:11

1 Answers1

1

The question consists of 2 parts:

  • Get a list of all deployed applications - After reviewing Tomcat's API, I found several relevant deployment code parts which can be instrumented: WarWatcher.java (allows to detect changes), and we can also see the apps from - UserConfig.java which is called on startup (instrumentation can be done on setDirectory name etc.), and of course HostConfig.java that is called on stratup:

    protected void org.apache.catalina.startup.HostConfig.deployWARs(java.io.File, java.lang.String[])
    
    protected void org.apache.catalina.startup.HostConfig.deployApps()
    
    protected void org.apache.catalina.startup.HostConfig.deployWAR(org.apache.catalina.util.ContextName, java.io.File)
    

    In addition - you can check the argument for:

    protected boolean org.apache.catalina.startup.HostConfig.deploymentExists(java.lang.String)
    

    It includes the war/folder name (which usually means the application name+-).

  • Get the root application name - This can be done by using ServletContext.getRealPath() - It returns the folder name, from which the war name can be extracted (and can be used, in my case at least as the app name).

Lin
  • 2,445
  • 5
  • 27
  • 37
  • `getRealPath()` doesn't return application names, especially of the root application. – user207421 Sep 20 '16 at 23:36
  • @EJP - it returns the folder name, which is what I was looking for, since it can be used to extract a the war name (which usually can be used as the app name). – Lin Sep 21 '16 at 08:14