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: | 625 / 147 |
Referenced in: | [show references] |