+1, nice feature. as many projects prefer spring boot for integration.

Collect service information for Spring Boot applications
Service information (loaded libraries) are not collected for Spring Boot applications except for cases where they are packaged as _war_ files and are loaded on a container (such as Tomcat).

A lot of Spring Boot applications are run as an executable jar (or war), so it would be useful to collect these information in these cases as well.

bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java
bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/interceptor/LauncherLaunchInterceptor.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java
profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentInfoSenderTest.java profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolderTest.java
diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java
index 9dd936122cbd..ced882dfec78 100644
--- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java
+++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/ServerMetaDataHolder.java
@@ -33,7 +33,7 @@ public interface ServerMetaDataHolder {
     
     void removeListener(ServerMetaDataListener listener);
     
-    void publishServerMetaData();
+    void notifyListeners();
     
     interface ServerMetaDataListener {
         
diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java
index ac9c8b4a3410..71343f464083 100644
--- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java
+++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/resolver/condition/MainClassCondition.java
@@ -90,8 +90,9 @@ private String getMainClassName(SimpleProperty property) {
             logger.warn("Error retrieving main class from [{}]", property.getClass().getName());
             return NOT_FOUND;
         } else {
+            JarFile executableArchive = null;
             try {
-                JarFile executableArchive = new JarFile(javaCommand);
+                executableArchive = new JarFile(javaCommand);
                 return extractMainClassFromArchive(executableArchive);
             } catch (IOException e) {
                 // If it's not a valid java archive, VM shouldn't start in the first place.
@@ -101,6 +102,14 @@ private String getMainClassName(SimpleProperty property) {
                 // fail-safe, application shouldn't not start because of this
                 logger.warn("Error retrieving main class from java command : [{}]", javaCommand, e);
                 return NOT_FOUND;
+            } finally {
+                if (executableArchive != null) {
+                    try {
+                        executableArchive.close();
+                    } catch (IOException e) {
+                        logger.warn("Error closing jarFile : [{}]", executableArchive.getName(), e);
+                    }
+                }
             }
         }
     }
diff --git a/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java
index 89da3cd0205c..83c66de9ee4c 100644
--- a/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java
+++ b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootConstants.java
@@ -32,4 +32,6 @@ private SpringBootConstants() {
     public static final ServiceType SERVICE_TYPE = ServiceTypeFactory.of(1210, NAME, RECORD_STATISTICS);
 
     public static final String BOOTSTRAP_MAIN_PREFIX = "org.springframework.boot.loader.";
+
+    public static final String ROOT_CONTEXT_KEY = "Spring Boot";
 }
diff --git a/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java
index 852a369aced6..d4c109edf520 100644
--- a/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java
+++ b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/SpringBootPlugin.java
@@ -16,17 +16,54 @@
 
 package com.navercorp.pinpoint.plugin.spring.boot;
 
+import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
+import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
+import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod;
+import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor;
+import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformCallback;
+import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplate;
+import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplateAware;
 import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin;
 import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext;
 
+import java.security.ProtectionDomain;
+
 /**
  * @author HyunGil Jeong
  */
-public class SpringBootPlugin implements ProfilerPlugin {
+public class SpringBootPlugin implements ProfilerPlugin, TransformTemplateAware {
+
+    private TransformTemplate transformTemplate;
 
     @Override
     public void setup(ProfilerPluginSetupContext context) {
         context.addApplicationTypeDetector(new SpringBootDetector());
+
+        addLauncherEditor();
+    }
+
+    @Override
+    public void setTransformTemplate(TransformTemplate transformTemplate) {
+        this.transformTemplate = transformTemplate;
     }
 
+    private void addLauncherEditor() {
+        transformTemplate.transform("org.springframework.boot.loader.Launcher", new TransformCallback() {
+
+            @Override
+            public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className,
+                                        Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
+                                        byte[] classfileBuffer) throws InstrumentException {
+
+                InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer);
+                InstrumentMethod method = target.getDeclaredMethod("launch", "java.lang.String[]", "java.lang.String", "java.lang.ClassLoader");
+                if (method != null) {
+                    method.addInterceptor("com.navercorp.pinpoint.plugin.spring.boot.interceptor.LauncherLaunchInterceptor");
+                }
+
+                return target.toBytecode();
+            }
+
+        });
+    }
 }
diff --git a/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/interceptor/LauncherLaunchInterceptor.java b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/interceptor/LauncherLaunchInterceptor.java
new file mode 100644
index 000000000000..852d7637f379
--- /dev/null
+++ b/plugins/spring-boot/src/main/java/com/navercorp/pinpoint/plugin/spring/boot/interceptor/LauncherLaunchInterceptor.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 NAVER Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.navercorp.pinpoint.plugin.spring.boot.interceptor;
+
+import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder;
+import com.navercorp.pinpoint.bootstrap.context.TraceContext;
+import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
+import com.navercorp.pinpoint.bootstrap.logging.PLogger;
+import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
+import com.navercorp.pinpoint.plugin.spring.boot.SpringBootConstants;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author HyunGil Jeong
+ */
+public class LauncherLaunchInterceptor implements AroundInterceptor {
+
+    private final static String PATH_SEPARATOR = "/";
+    private final static String JAR_SEPARATOR = "!";
+
+    private final PLogger logger = PLoggerFactory.getLogger(this.getClass());
+    private final boolean isDebug = logger.isDebugEnabled();
+
+    private final TraceContext traceContext;
+
+    public LauncherLaunchInterceptor(TraceContext traceContext) {
+        this.traceContext = traceContext;
+    }
+
+    @Override
+    public void before(Object target, Object[] args) {
+        if (isDebug) {
+            logger.beforeInterceptor(target, args);
+        }
+        if (!validate(target, args)) {
+            return;
+        }
+        String serviceName = createServiceName(target);
+        URLClassLoader classLoader = (URLClassLoader) args[2];
+        URL[] urls = classLoader.getURLs();
+        List<String> loadedJarNames = new ArrayList<String>(extractLibJarNamesFromURLs(urls));
+        ServerMetaDataHolder holder = this.traceContext.getServerMetaDataHolder();
+        holder.addServiceInfo(serviceName, loadedJarNames);
+        holder.notifyListeners();
+    }
+
+    @Override
+    public void after(Object target, Object[] args, Object result, Throwable throwable) {
+        // Do nothing
+    }
+
+    private String createServiceName(Object target) {
+        StringBuilder sb = new StringBuilder(SpringBootConstants.ROOT_CONTEXT_KEY);
+        sb.append(" (").append(target.getClass().getSimpleName()).append(")");
+        return sb.toString();
+    }
+
+    private boolean validate(Object target, Object[] args) {
+        if (target == null || args == null) {
+            return false;
+        }
+        if (args.length < 3) {
+            return false;
+        }
+        if (!(args[2] instanceof URLClassLoader)) {
+            return false;
+        }
+        return true;
+    }
+
+    private Set<String> extractLibJarNamesFromURLs(URL[] urls) {
+        if (urls == null) {
+            return Collections.emptySet();
+        }
+        Set<String> libJarNames = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+        for (URL url : urls) {
+            try {
+                String libJarName = extractLibJarName(url);
+                if (libJarName.length() > 0) {
+                    libJarNames.add(libJarName);
+                }
+            } catch (Exception e) {
+                // safety net
+                logger.warn("Error extracting library name", e);
+            }
+        }
+        return libJarNames;
+    }
+
+    private String extractLibJarName(URL url) {
+        String protocol = url.getProtocol();
+        String path = url.getPath().replaceAll("\\\\", PATH_SEPARATOR);
+        if (protocol.equals("file")) {
+            return extractNameFromFile(path);
+        } else if (protocol.equals("jar")) {
+            return extractNameFromJar(path);
+        } else {
+            return "";
+        }
+    }
+
+    private String extractNameFromFile(String fileUri) {
+        int lastIndexOfSeparator = fileUri.lastIndexOf(PATH_SEPARATOR);
+        if (lastIndexOfSeparator < 0) {
+            return fileUri;
+        } else {
+            return fileUri.substring(lastIndexOfSeparator + 1);
+        }
+    }
+
+    private String extractNameFromJar(String jarUri) {
+        String uri = jarUri.substring(0, jarUri.lastIndexOf(JAR_SEPARATOR));
+        int rootJarEndIndex = uri.indexOf(JAR_SEPARATOR);
+        if (rootJarEndIndex < 0) {
+            return extractNameFromFile(uri);
+        }
+        String rootJarFileUri = extractNameFromFile(uri.substring(0, rootJarEndIndex));
+        StringBuilder sb = new StringBuilder(rootJarFileUri);
+        sb.append(uri.substring(rootJarEndIndex));
+        return sb.toString();
+    }
+
+}
diff --git a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java
index 0917e1c0d732..81766e7fe549 100644
--- a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java
+++ b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/TomcatPlugin.java
@@ -177,16 +177,17 @@ private void addWebappLoaderEditor() {
             public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException {
                 InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer);
 
-                // Tomcat 6 - org.apache.catalina.loader.WebappLoader.start()
-                InstrumentMethod startEditor = target.getDeclaredMethod("start");
-                if (startEditor != null) {
-                    startEditor.addInterceptor("com.navercorp.pinpoint.plugin.tomcat.interceptor.WebappLoaderStartInterceptor");
+                InstrumentMethod startMethod = null;
+                if (target.hasDeclaredMethod("start")) {
+                    // Tomcat 6 - org.apache.catalina.loader.WebappLoader.start()
+                    startMethod = target.getDeclaredMethod("start");
+                } else if (target.hasDeclaredMethod("startInternal")) {
+                    // Tomcat 7, 8 - org.apache.catalina.loader.WebappLoader.startInternal()
+                    startMethod = target.getDeclaredMethod("startInternal");
                 }
 
-                // Tomcat 7, 8 - org.apache.catalina.loader.WebappLoader.startInternal()
-                InstrumentMethod startInternalEditor = target.getDeclaredMethod("startInternal");
-                if (startInternalEditor != null) {
-                    startInternalEditor.addInterceptor("com.navercorp.pinpoint.plugin.tomcat.interceptor.WebappLoaderStartInterceptor");
+                if (startMethod != null) {
+                    startMethod.addInterceptor("com.navercorp.pinpoint.plugin.tomcat.interceptor.WebappLoaderStartInterceptor");
                 }
 
                 return target.toBytecode();
diff --git a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java
index 9e961e25efd9..26e90855be09 100644
--- a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java
+++ b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/ConnectorInitializeInterceptor.java
@@ -16,6 +16,7 @@
 
 package com.navercorp.pinpoint.plugin.tomcat.interceptor;
 
+import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder;
 import org.apache.catalina.connector.Connector;
 
 import com.navercorp.pinpoint.bootstrap.context.TraceContext;
@@ -49,7 +50,9 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
         }
         if (target instanceof Connector) {
             final Connector connector = (Connector) target;
-            this.traceContext.getServerMetaDataHolder().addConnector(connector.getProtocol(), connector.getPort());
+            ServerMetaDataHolder holder = this.traceContext.getServerMetaDataHolder();
+            holder.addConnector(connector.getProtocol(), connector.getPort());
+            holder.notifyListeners();
         }
     }
 }
diff --git a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java
index ecc3bfbb6fc2..b0cb2dab25db 100644
--- a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java
+++ b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardServiceStartInterceptor.java
@@ -16,6 +16,7 @@
 
 package com.navercorp.pinpoint.plugin.tomcat.interceptor;
 
+import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder;
 import org.apache.catalina.util.ServerInfo;
 
 import com.navercorp.pinpoint.bootstrap.context.TraceContext;
@@ -50,8 +51,8 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
         }
 
         String serverInfo = ServerInfo.getServerInfo();
-        this.traceContext.getServerMetaDataHolder().setServerName(serverInfo);
-        // Service started. Publish server meta data.
-        this.traceContext.getServerMetaDataHolder().publishServerMetaData();
+        ServerMetaDataHolder holder = this.traceContext.getServerMetaDataHolder();
+        holder.setServerName(serverInfo);
+        holder.notifyListeners();
     }
 }
diff --git a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java
index a980fefba7e6..0b663c228d6b 100644
--- a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java
+++ b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/WebappLoaderStartInterceptor.java
@@ -18,12 +18,15 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.Engine;
@@ -139,19 +142,24 @@ private List<String> extractLibJarNamesFromURLs(URL[] urls) {
         }
         List<String> libJarNames = new ArrayList<String>(urls.length);
         for (URL url : urls) {
-            String libJarName = extractLibJarName(url);
-            if (libJarName.length() > 0) {
-                libJarNames.add(libJarName);
+            try {
+                URI uri =  url.toURI();
+                String libJarName = extractLibJarName(uri);
+                if (libJarName.length() > 0) {
+                    libJarNames.add(libJarName);
+                }
+            } catch (URISyntaxException e) {
+                // ignore invalid formats
+                logger.warn("Invalid library url found : [{}]", url, e);
+            } catch (Exception e) {
+                logger.warn("Error extracting library name", e);
             }
         }
         return libJarNames;
     }
     
-    private String extractLibJarName(URL url) {
-        if (url == null) {
-            return "";
-        }
-        String jarName = url.toString();
+    private String extractLibJarName(URI uri) {
+        String jarName = uri.toString();
         if (jarName == null) {
             return "";
         }
@@ -164,7 +172,9 @@ private String extractLibJarName(URL url) {
     }
     
     private void dispatchLibJars(String contextKey, List<String> libJars) {
-        this.traceContext.getServerMetaDataHolder().addServiceInfo(contextKey, libJars);
+        ServerMetaDataHolder holder = this.traceContext.getServerMetaDataHolder();
+        holder.addServiceInfo(contextKey, libJars);
+        holder.notifyListeners();
     }
 
 }
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java
index 0b9f34830219..40bf8971a8d0 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolder.java
@@ -73,7 +73,7 @@ public void removeListener(ServerMetaDataListener listener) {
     }
 
     @Override
-    public void publishServerMetaData() {
+    public void notifyListeners() {
         final ServerMetaData serverMetaData = createServerMetaData();
         for (ServerMetaDataListener listener : this.listeners) {
             listener.publishServerMetaData(serverMetaData);

diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentInfoSenderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentInfoSenderTest.java
index 487f1b70eeb3..451b671b814c 100644
--- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentInfoSenderTest.java
+++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/AgentInfoSenderTest.java
@@ -359,13 +359,15 @@ public void serverMetaDataCouldBePublishedFromMultipleThreads() throws Interrupt
         metaDataContext.addListener(agentInfoSender);
         // When
         for (int i = 0; i < threadCount; ++i) {
+            final String serviceName = "/name" + i;
             executorService.submit(new Callable<Void>() {
                 @Override
                 public Void call() throws Exception {
                     initLatch.countDown();
                     try {
                         startLatch.await();
-                        metaDataContext.publishServerMetaData();
+                        metaDataContext.addServiceInfo(serviceName, Collections.<String>emptyList());
+                        metaDataContext.notifyListeners();
                     } catch (final Throwable t) {
                         exceptions.add(t);
                     } finally {
diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolderTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolderTest.java
index 2d51b4582380..bced0b1ee73b 100644
--- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolderTest.java
+++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultServerMetaDataHolderTest.java
@@ -35,7 +35,6 @@
 
 import com.navercorp.pinpoint.bootstrap.context.ServerMetaData;
 import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder;
-import com.navercorp.pinpoint.profiler.context.DefaultServerMetaDataHolder;
 import com.navercorp.pinpoint.test.TestableServerMetaDataListener;
 
 /**
@@ -83,7 +82,7 @@ public Void call() throws Exception {
                     try {
                         startLatch.await();
                         metaDataContext.addServiceInfo(serviceName, serviceLibs);
-                        metaDataContext.publishServerMetaData();
+                        metaDataContext.notifyListeners();
                     } catch (final Throwable t) {
                         exceptions.add(t);
                     } finally {
@@ -129,7 +128,7 @@ public Void call() throws Exception {
                         try {
                             startLatch.await();
                             metaDataContext.addServiceInfo(serviceName, serviceLibs);
-                            metaDataContext.publishServerMetaData();
+                            metaDataContext.notifyListeners();
                         } catch (Throwable t) {
                             exceptions.add(t);
                         } finally {
