001
014
015 package com.liferay.portal.aspectj;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.util.StreamUtil;
021
022 import java.io.File;
023 import java.io.IOException;
024 import java.io.InputStream;
025
026 import java.net.URL;
027 import java.net.URLClassLoader;
028
029 import java.nio.file.Files;
030
031 import java.security.ProtectionDomain;
032
033 import java.util.Arrays;
034
035 import org.aspectj.bridge.AbortException;
036
037
040 public class WeavingClassLoader extends URLClassLoader {
041
042 public WeavingClassLoader(
043 URL[] urls, Class<?>[] aspectClasses, File dumpDir) {
044
045 super(urls, null);
046
047 _dumpDir = dumpDir;
048
049 _urlWeavingAdapter = new URLWeavingAdapter(urls, aspectClasses);
050 }
051
052 @Override
053 protected Class<?> findClass(String name) throws ClassNotFoundException {
054 String resourcePath = name.replace('.', '/') + ".class";
055
056 InputStream inputStream = getResourceAsStream(resourcePath);
057
058 byte[] data = null;
059
060 try {
061 if (inputStream == null) {
062
063
064
065 data = _urlWeavingAdapter.removeGeneratedClassDate(name);
066 }
067 else {
068 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
069 new UnsyncByteArrayOutputStream();
070
071 StreamUtil.transfer(inputStream, unsyncByteArrayOutputStream);
072
073 data = unsyncByteArrayOutputStream.toByteArray();
074 }
075
076 if (data == null) {
077 throw new ClassNotFoundException(name);
078 }
079
080 byte[] oldData = data;
081
082 try {
083 data = _urlWeavingAdapter.weaveClass(name, data, false);
084 }
085 catch (AbortException ae) {
086 if (_log.isWarnEnabled()) {
087 _log.warn("Abort weaving class " + name, ae);
088 }
089 }
090
091 if (Arrays.equals(oldData, data)) {
092 return _generateClass(name, data);
093 }
094
095 if (_dumpDir != null) {
096 File dumpFile = new File(_dumpDir, resourcePath);
097
098 File dumpDir = dumpFile.getParentFile();
099
100 dumpDir.mkdirs();
101
102 Files.write(dumpFile.toPath(), data);
103
104 if (_log.isInfoEnabled()) {
105 _log.info(
106 "Woven class " + name + " result in " +
107 dumpFile.getCanonicalPath());
108 }
109 }
110 else {
111 if (_log.isInfoEnabled()) {
112 _log.info("Woven class " + name);
113 }
114 }
115
116 return _generateClass(name, data);
117 }
118 catch (IOException ioe) {
119 throw new ClassNotFoundException(name, ioe);
120 }
121 }
122
123 private Class<?> _generateClass(String name, byte[] data) {
124 Class<?> clazz = defineClass(
125 name, data, 0, data.length, (ProtectionDomain)null);
126
127 String packageName = null;
128
129 int index = name.lastIndexOf('.');
130
131 if (index != -1) {
132 packageName = name.substring(0, index);
133 }
134
135 if (packageName != null) {
136 Package pkg = getPackage(packageName);
137
138 if (pkg == null) {
139 definePackage(
140 packageName, null, null, null, null, null, null, null);
141 }
142 }
143
144 return clazz;
145 }
146
147 private static final Log _log = LogFactoryUtil.getLog(
148 WeavingClassLoader.class);
149
150 private final File _dumpDir;
151 private final URLWeavingAdapter _urlWeavingAdapter;
152
153 }