1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.util;
19
20 import static org.junit.Assert.assertTrue;
21
22 import java.io.BufferedWriter;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.FileWriter;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.jar.JarEntry;
32 import java.util.jar.JarOutputStream;
33 import java.util.jar.Manifest;
34
35 import javax.tools.JavaCompiler;
36 import javax.tools.JavaFileObject;
37 import javax.tools.StandardJavaFileManager;
38 import javax.tools.ToolProvider;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.hadoop.conf.Configuration;
43 import org.apache.hadoop.fs.Path;
44
45
46
47
48 public class ClassLoaderTestHelper {
49 private static final Log LOG = LogFactory.getLog(ClassLoaderTestHelper.class);
50
51 private static final int BUFFER_SIZE = 4096;
52
53
54
55
56
57
58
59 private static boolean createJarArchive(File archiveFile, File[] tobeJared) {
60 try {
61 byte buffer[] = new byte[BUFFER_SIZE];
62
63 FileOutputStream stream = new FileOutputStream(archiveFile);
64 JarOutputStream out = new JarOutputStream(stream, new Manifest());
65
66 for (int i = 0; i < tobeJared.length; i++) {
67 if (tobeJared[i] == null || !tobeJared[i].exists()
68 || tobeJared[i].isDirectory()) {
69 continue;
70 }
71
72
73 JarEntry jarAdd = new JarEntry(tobeJared[i].getName());
74 jarAdd.setTime(tobeJared[i].lastModified());
75 out.putNextEntry(jarAdd);
76
77
78 FileInputStream in = new FileInputStream(tobeJared[i]);
79 while (true) {
80 int nRead = in.read(buffer, 0, buffer.length);
81 if (nRead <= 0)
82 break;
83 out.write(buffer, 0, nRead);
84 }
85 in.close();
86 }
87 out.close();
88 stream.close();
89 LOG.info("Adding classes to jar file completed");
90 return true;
91 } catch (Exception ex) {
92 LOG.error("Error: " + ex.getMessage());
93 return false;
94 }
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public static File buildJar(String testDir,
110 String className, String code) throws Exception {
111 return buildJar(testDir, className, code, testDir);
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125 public static File buildJar(String testDir,
126 String className, String code, String folder) throws Exception {
127 String javaCode = code != null ? code : "public class " + className + " {}";
128 Path srcDir = new Path(testDir, "src");
129 File srcDirPath = new File(srcDir.toString());
130 srcDirPath.mkdirs();
131 File sourceCodeFile = new File(srcDir.toString(), className + ".java");
132 BufferedWriter bw = Files.newBufferedWriter(sourceCodeFile.toPath(), StandardCharsets.UTF_8);
133 bw.write(javaCode);
134 bw.close();
135
136
137 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
138 ArrayList<String> srcFileNames = new ArrayList<String>();
139 srcFileNames.add(sourceCodeFile.toString());
140 StandardJavaFileManager fm = compiler.getStandardFileManager(null, null,
141 null);
142 Iterable<? extends JavaFileObject> cu =
143 fm.getJavaFileObjects(sourceCodeFile);
144 List<String> options = new ArrayList<String>();
145 options.add("-classpath");
146
147
148 String currentDir = new File(".").getAbsolutePath();
149 String classpath = currentDir + File.separator + "target"+ File.separator
150 + "classes" + System.getProperty("path.separator")
151 + System.getProperty("java.class.path") + System.getProperty("path.separator")
152 + System.getProperty("surefire.test.class.path");
153
154 options.add(classpath);
155 LOG.debug("Setting classpath to: " + classpath);
156
157 JavaCompiler.CompilationTask task = compiler.getTask(null, fm, null,
158 options, null, cu);
159 assertTrue("Compile file " + sourceCodeFile + " failed.", task.call());
160
161
162 String jarFileName = className + ".jar";
163 File jarFile = new File(folder, jarFileName);
164 jarFile.getParentFile().mkdirs();
165 if (!createJarArchive(jarFile,
166 new File[]{new File(srcDir.toString(), className + ".class")})){
167 assertTrue("Build jar file failed.", false);
168 }
169 return jarFile;
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183 public static void addJarFilesToJar(File targetJar,
184 String libPrefix, File... srcJars) throws Exception {
185 FileOutputStream stream = new FileOutputStream(targetJar);
186 JarOutputStream out = new JarOutputStream(stream, new Manifest());
187 byte buffer[] = new byte[BUFFER_SIZE];
188
189 for (File jarFile: srcJars) {
190
191 JarEntry jarAdd = new JarEntry(libPrefix + jarFile.getName());
192 jarAdd.setTime(jarFile.lastModified());
193 out.putNextEntry(jarAdd);
194
195
196 FileInputStream in = new FileInputStream(jarFile);
197 while (true) {
198 int nRead = in.read(buffer, 0, buffer.length);
199 if (nRead <= 0)
200 break;
201 out.write(buffer, 0, nRead);
202 }
203 in.close();
204 }
205 out.close();
206 stream.close();
207 LOG.info("Adding jar file to outer jar file completed");
208 }
209
210 static String localDirPath(Configuration conf) {
211 return conf.get(ClassLoaderBase.LOCAL_DIR_KEY)
212 + File.separator + "jars" + File.separator;
213 }
214
215 }