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