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 _urlWeavingAdaptor = new URLWeavingAdaptor(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 = _urlWeavingAdaptor.removeGeneratedClassDate(name);
065 }
066 else {
067 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
068 new UnsyncByteArrayOutputStream();
069
070 StreamUtil.transfer(
071 inputStream, unsyncByteArrayOutputStream, true);
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 = _urlWeavingAdaptor.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 FileOutputStream fileOutputStream = new FileOutputStream(
103 dumpFile);
104
105 fileOutputStream.write(data);
106
107 fileOutputStream.close();
108
109 if (_log.isInfoEnabled()) {
110 _log.info(
111 "Woven class " + name + " result in " +
112 dumpFile.getCanonicalPath());
113 }
114 }
115 else {
116 if (_log.isInfoEnabled()) {
117 _log.info("Woven class " + name);
118 }
119 }
120
121 return _generateClass(name, data);
122 }
123 catch (IOException ioe) {
124 throw new ClassNotFoundException(name, ioe);
125 }
126 }
127
128 private Class<?> _generateClass(String name, byte[] data) {
129 Class<?> clazz = defineClass(
130 name, data, 0, data.length, (ProtectionDomain)null);
131
132 String packageName = null;
133
134 int index = name.lastIndexOf('.');
135
136 if (index != -1) {
137 packageName = name.substring(0, index);
138 }
139
140 if (packageName != null) {
141 Package pkg = getPackage(packageName);
142
143 if (pkg == null) {
144 definePackage(
145 packageName, null, null, null, null, null, null, null);
146 }
147 }
148
149 return clazz;
150 }
151
152 private static Log _log = LogFactoryUtil.getLog(WeavingClassLoader.class);
153
154 private File _dumpDir;
155 private URLWeavingAdaptor _urlWeavingAdaptor;
156
157 }