/*
 * Copyright 2017, OpenSkywalking Organization All rights reserved.
 *
 * 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.
 *
 * Project repository: https://github.com/OpenSkywalking/skywalking
 */

package org.skywalking.apm.agent;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.logging.api.ILog;
import org.skywalking.apm.agent.core.logging.api.LogManager;

/**
 * @author wu-sheng
 */
public enum InstrumentDebuggingClass {
    INSTANCE;

    private static final ILog logger = LogManager.getLogger(InstrumentDebuggingClass.class);
    private File debuggingClassesRootPath;

    public void log(TypeDescription typeDescription, DynamicType dynamicType) {
        if (!Config.Agent.IS_OPEN_DEBUGGING_CLASS) {
            return;
        }

        /**
         * try to do I/O things in synchronized way, to avoid unexpected situations.
         */
        synchronized (INSTANCE) {
            try {
                if (debuggingClassesRootPath == null) {
                    try {
                        debuggingClassesRootPath = new File(AgentPackagePath.getPath(), "/debugging");
                        if (!debuggingClassesRootPath.exists()) {
                            debuggingClassesRootPath.mkdir();
                        }
                    } catch (AgentPackageNotFoundException e) {
                        logger.error(e, "Can't find the root path for creating /debugging folder.");
                    }
                }

                File newClassFileFolder = new File(debuggingClassesRootPath, typeDescription.getPackage().getActualName().replaceAll("\\.", "/"));
                if (!newClassFileFolder.exists()) {
                    newClassFileFolder.mkdirs();
                }
                File newClassFile = new File(newClassFileFolder, typeDescription.getSimpleName() + ".class");
                FileOutputStream fos = null;
                try {
                    if (newClassFile.exists()) {
                        newClassFile.delete();
                    }
                    newClassFile.createNewFile();
                    fos = new FileOutputStream(newClassFile);
                    fos.write(dynamicType.getBytes());
                    fos.flush();
                } catch (IOException e) {
                    logger.error(e, "Can't save class {} to file." + typeDescription.getActualName());
                } finally {
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {

                        }
                    }
                }
            } catch (Throwable t) {
                logger.error(t, "Save debugging classes fail.");
            }
        }
    }
}

@@ -758,41 +758,8 @@
 le;%0A
-import java.io.FileOutputStream;%0A
 impo
@@ -2288,1134 +2288,224 @@
     
-File newClassFileFolder = new File(debuggingClassesRootPath, typeDescription.getPackage().getActualName().replaceAll(%22%5C%5C.%22, %22/%22));%0A                if (!newClassFileFolder.exists()) %7B%0A                    newClassFileFolder.mkdirs();%0A                %7D%0A                File newClassFile = new File(newClassFileFolder, typeDescription.getSimpleName() + %22.class%22);%0A                FileOutputStream fos = null;%0A                try %7B%0A                    if (newClassFile.exists()) %7B%0A                        newClassFile.delete();%0A                    %7D%0A                    newClassFile.createNewFile();%0A                    fos = new FileOutputStream(newClassFile);%0A                    fos.write(dynamicType.getBytes());%0A                    fos.flush();%0A                %7D catch (IOException e) %7B%0A                    logger.error(e, %22Can't save class %7B%7D to file.%22 + typeDescription.getActualName());%0A                %7D finally %7B%0A                    if (fos != null) %7B%0A                        try %7B%0A                            fos.close();%0A                        %7D catch (IOException e) %7B%0A%0A                        %7D%0A                    %7D
+try %7B%0A                    dynamicType.saveIn(debuggingClassesRootPath);%0A                %7D catch (IOException e) %7B%0A                    logger.error(e, %22Can't save class %7B%7D to file.%22 + typeDescription.getActualName());
 %0A   

Use byte buddy saveIn API instead of my own implementation.