1 | import java.io.*; |
2 | import java.lang.reflect.InvocationTargetException; |
3 | import java.lang.reflect.Method; |
4 | import java.net.MalformedURLException; |
5 | import java.net.URL; |
6 | import java.net.URLClassLoader; |
7 | import java.util.ArrayList; |
8 | import java.util.List; |
9 | |
10 | /** |
11 | * javax by Stefan Reich (www.superinformatiker.de, info@superinformatiker.de) |
12 | * |
13 | * jaxax compiles and runs a bunch of Java sources in one step. |
14 | * |
15 | * Syntax: |
16 | * javax (searches for sources in current dir) |
17 | * javax srcdir (searches in given directory) |
18 | * |
19 | * Main class must be called "main" in default package. |
20 | * |
21 | * Requirements: |
22 | * Java 6 or higher - JDK (javac) must be in path |
23 | * |
24 | * Limitations: |
25 | * Linux only, right now (invokes bash to call javac) |
26 | * Can't pass arguments to invoked program yet (would be easy to add) |
27 | * |
28 | * TODO: delete .class files at program end |
29 | */ |
30 | |
31 | public class x1 {
|
32 | public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
|
33 | File srcDir = new File(args.length == 0 ? "." : args[0]); |
34 | List<File> sources = new ArrayList<File>(); |
35 | System.out.println("Scanning for sources in " + srcDir.getPath());
|
36 | scanForSources(srcDir, sources); |
37 | if (sources.isEmpty()) {
|
38 | System.out.println("No sources found");
|
39 | return; |
40 | } |
41 | File optionsFile = File.createTempFile("javax", "");
|
42 | File classesDir = new File(System.getProperty("user.home"), ".javax/" + System.currentTimeMillis());
|
43 | System.out.println("Compiling " + sources.size() + " source(s) to " + classesDir.getPath());
|
44 | String options = "-d " + bashQuote(classesDir.getPath()); |
45 | writeOptions(sources, optionsFile, options); |
46 | classesDir.mkdirs(); |
47 | invokeJavac(optionsFile); |
48 | System.out.println("Running program (class main.java)\n");
|
49 | runProgram(classesDir); |
50 | } |
51 | |
52 | private static void runProgram(File classesDir) throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
53 | URLClassLoader classLoader = new URLClassLoader(new URL[]{classesDir.toURI().toURL()});
|
54 | Class<?> mainClass = classLoader.loadClass("main");
|
55 | Method main = mainClass.getMethod("main", String[].class);
|
56 | main.invoke(null, (Object) new String[0]); |
57 | } |
58 | |
59 | private static void invokeJavac(File optionsFile) throws IOException {
|
60 | String javacOutput = backtick("javac " + bashQuote("@" + optionsFile.getPath()));
|
61 | System.out.println(javacOutput); |
62 | } |
63 | |
64 | private static void writeOptions(List<File> sources, File sourcesFile, String moreOptions) throws IOException {
|
65 | FileWriter writer = new FileWriter(sourcesFile); |
66 | for (File source : sources) |
67 | writer.write(bashQuote(source.getPath()) + " "); |
68 | writer.write(moreOptions); |
69 | writer.close(); |
70 | } |
71 | |
72 | private static void scanForSources(File source, List<File> sources) {
|
73 | if (source.isFile() && source.getName().endsWith(".java"))
|
74 | sources.add(source); |
75 | else if (source.isDirectory()) {
|
76 | File[] files = source.listFiles(); |
77 | for (File file : files) |
78 | scanForSources(file, sources); |
79 | } |
80 | } |
81 | |
82 | public static String backtick(String cmd) throws IOException {
|
83 | File outFile = File.createTempFile("_backtick", "");
|
84 | File scriptFile = File.createTempFile("_backtick", "");
|
85 | |
86 | String command = cmd + ">" + bashQuote(outFile.getPath()) + " 2>&1"; |
87 | //Log.info("[Backtick] " + command);
|
88 | try {
|
89 | saveTextFile(scriptFile.getPath(), command); |
90 | String[] command2 = {"/bin/bash", scriptFile.getPath() };
|
91 | Process process = Runtime.getRuntime().exec(command2); |
92 | try {
|
93 | process.waitFor(); |
94 | } catch (InterruptedException e) {
|
95 | throw new RuntimeException(e); |
96 | } |
97 | int value = process.exitValue(); |
98 | //Log.info("exit value: " + value);
|
99 | return loadTextFile(outFile.getPath(), ""); |
100 | } finally {
|
101 | scriptFile.delete(); |
102 | } |
103 | } |
104 | |
105 | /** possoibly improvable */ |
106 | public static String bashQuote(String text) {
|
107 | if (text == null) return null; |
108 | return "\"" + text |
109 | .replace("\\", "\\\\")
|
110 | .replace("\"", "\\\"")
|
111 | .replace("\n", "\\n")
|
112 | .replace("\r", "\\r") + "\"";
|
113 | } |
114 | |
115 | public final static String charsetForTextFiles = "UTF8"; |
116 | |
117 | /** writes safely (to temp file, then rename) */ |
118 | public static void saveTextFile(String fileName, String contents) throws IOException {
|
119 | File file = new File(fileName); |
120 | File parentFile = file.getParentFile(); |
121 | if (parentFile != null) |
122 | parentFile.mkdirs(); |
123 | String tempFileName = fileName + "_temp"; |
124 | FileOutputStream fileOutputStream = new FileOutputStream(tempFileName); |
125 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, charsetForTextFiles); |
126 | PrintWriter printWriter = new PrintWriter(outputStreamWriter); |
127 | printWriter.print(contents); |
128 | printWriter.close(); |
129 | if (file.exists() && !file.delete()) |
130 | throw new IOException("Can't delete " + fileName);
|
131 | |
132 | if (!new File(tempFileName).renameTo(file)) |
133 | throw new IOException("Can't rename " + tempFileName + " to " + fileName);
|
134 | } |
135 | |
136 | public static String loadTextFile(String fileName, String defaultContents) throws IOException {
|
137 | if (!new File(fileName).exists()) |
138 | return defaultContents; |
139 | |
140 | FileInputStream fileInputStream = new FileInputStream(fileName); |
141 | InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charsetForTextFiles); |
142 | return loadTextFile(inputStreamReader); |
143 | } |
144 | |
145 | public static String loadTextFile(Reader reader) throws IOException {
|
146 | StringBuilder builder = new StringBuilder(); |
147 | try {
|
148 | BufferedReader bufferedReader = new BufferedReader(reader); |
149 | String line; |
150 | while ((line = bufferedReader.readLine()) != null) |
151 | builder.append(line).append('\n');
|
152 | } finally {
|
153 | reader.close(); |
154 | } |
155 | return builder.length() == 0 ? "" : builder.substring(0, builder.length()-1); |
156 | } |
157 | } |
Will try to make it Windows-compatible...! Began life as a copy of #581
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #582 |
| Snippet name: | Working on: x1.java (JavaX Level 1) |
| Eternal ID of this version: | #582/1 |
| Text MD5: | 792b1f3dc0b66cb1c2fd7cdb6b860776 |
| Author: | stefan |
| Category: | |
| Type: | Java source code |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2015-04-20 21:10:37 |
| Source code size: | 6106 bytes / 157 lines |
| Pitched / IR pitched: | No / Yes |
| Views / Downloads: | 894 / 211 |
| Referenced in: | [show references] |