Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/interoperability/RMIMessengerClient.java |
— | — | @@ -171,8 +171,14 @@ |
172 | 172 | log.debug(" \\-> got: "+res); |
173 | 173 | return res; |
174 | 174 | } catch (Exception e) { |
175 | | - log.warn("Error invoking remote method searchMainPart on host "+host); |
176 | | - return null; |
| 175 | + // invalidate the searcher cache |
| 176 | + if(cache == null) |
| 177 | + cache = SearcherCache.getInstance(); |
| 178 | + cache.invalidateSearchable(iid,host); |
| 179 | + SearchResults res = new SearchResults(); |
| 180 | + res.retry(); |
| 181 | + log.warn("Error invoking remote method searchPart on host "+host); |
| 182 | + return res; |
177 | 183 | } |
178 | 184 | } |
179 | 185 | |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/benchmark/Benchmark.java |
— | — | @@ -229,7 +229,9 @@ |
230 | 230 | return; |
231 | 231 | } |
232 | 232 | } |
233 | | - if("en".equals(lang) || "de".equals(lang) || "es".equals(lang) || "fr".equals(lang) || "it".equals(lang) || "pt".equals(lang)) |
| 233 | + if(wordfile != null) |
| 234 | + terms = new StreamTerms(wordfile); |
| 235 | + else if("en".equals(lang) || "de".equals(lang) || "es".equals(lang) || "fr".equals(lang) || "it".equals(lang) || "pt".equals(lang)) |
234 | 236 | terms = new WordTerms("./lib/dict/terms-"+lang+".txt.gz"); |
235 | 237 | else if(lang.equals("sample")) |
236 | 238 | terms = new SampleTerms(); |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/statistics/Statistics.java |
— | — | @@ -6,6 +6,7 @@ |
7 | 7 | import java.text.MessageFormat; |
8 | 8 | |
9 | 9 | import org.apache.log4j.Logger; |
| 10 | +import org.wikimedia.lsearch.util.Command; |
10 | 11 | |
11 | 12 | /** |
12 | 13 | * Class that reports statistics to ganglia daemon via gmetric. |
— | — | @@ -142,19 +143,10 @@ |
143 | 144 | String command = MessageFormat.format( |
144 | 145 | "/usr/bin/gmetric --name={0} --value={1,number,#.###} --type=double --units={2} --dmax={3} {4} {5}", |
145 | 146 | new Object [] { name, new Double(value), units, new Long(maxDelta / 1000L), portOverride, ifOverride}); |
146 | | - Process gmetric; |
147 | 147 | try { |
148 | | - log.debug("Executing shell command "+command); |
149 | | - gmetric = Runtime.getRuntime().exec(command); |
150 | | - gmetric.waitFor(); |
151 | | - if(gmetric.exitValue()!=0){ |
152 | | - log.warn("Got exit value "+gmetric.exitValue()+" while executing "+command); |
153 | | - //log.warn("Error was: "+new BufferedReader(new InputStreamReader(gmetric.getInputStream())).readLine()); |
154 | | - } |
| 148 | + Command.exec(command); |
155 | 149 | } catch (IOException e) { |
156 | 150 | e.printStackTrace(); |
157 | | - } catch (InterruptedException e) { |
158 | | - e.printStackTrace(); |
159 | | - } |
| 151 | + } |
160 | 152 | } |
161 | 153 | } |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/storage/MySQLStorage.java |
— | — | @@ -235,7 +235,7 @@ |
236 | 236 | } catch (SQLException e) { |
237 | 237 | } |
238 | 238 | } |
239 | | - |
| 239 | + |
240 | 240 | /** Creates table if it doesn't exist */ |
241 | 241 | protected void verifyTable(String name, String dbname, Connection conn) throws IOException { |
242 | 242 | // verify if table exists |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/search/SearcherCache.java |
— | — | @@ -15,6 +15,7 @@ |
16 | 16 | |
17 | 17 | import org.apache.log4j.Level; |
18 | 18 | import org.apache.log4j.Logger; |
| 19 | +import org.apache.lucene.index.Term; |
19 | 20 | import org.apache.lucene.search.IndexSearcher; |
20 | 21 | import org.apache.lucene.search.Searchable; |
21 | 22 | import org.apache.lucene.search.SearchableMul; |
— | — | @@ -60,11 +61,14 @@ |
61 | 62 | } |
62 | 63 | } |
63 | 64 | |
64 | | - /** Holds OPEN_SEARCHERS num of index searchers, for multiprocessor workstations */ |
| 65 | + /** Holds a number of index searchers, for multiprocessor workstations */ |
65 | 66 | public static class SearcherPool { |
66 | 67 | IndexSearcherMul searchers[]; |
| 68 | + IndexId iid; |
| 69 | + int index = 0; |
67 | 70 | |
68 | 71 | SearcherPool(IndexId iid, String path, int poolsize) throws IOException { |
| 72 | + this.iid = iid; |
69 | 73 | searchers = new IndexSearcherMul[poolsize]; |
70 | 74 | for(int i=0;i<poolsize;i++){ |
71 | 75 | searchers[i] = open(iid, path); |
— | — | @@ -73,7 +77,7 @@ |
74 | 78 | |
75 | 79 | private IndexSearcherMul open(IndexId iid, String path) throws IOException { |
76 | 80 | IndexSearcherMul searcher = null; |
77 | | - log.debug("Openning local index for "+iid); |
| 81 | + log.debug("Opening local index for "+iid); |
78 | 82 | if(!iid.isMySearch()) |
79 | 83 | throw new IOException(iid+" is not searched by this host."); |
80 | 84 | if(iid.isLogical()) |
— | — | @@ -91,7 +95,10 @@ |
92 | 96 | } |
93 | 97 | |
94 | 98 | IndexSearcherMul get(){ |
95 | | - return searchers[(int)(Math.random()*searchers.length)]; |
| 99 | + if(index >= searchers.length) |
| 100 | + index = 0; |
| 101 | + log.debug("Using "+iid+" searcher "+index); |
| 102 | + return searchers[index++]; |
96 | 103 | } |
97 | 104 | |
98 | 105 | } |
— | — | @@ -277,7 +284,7 @@ |
278 | 285 | protected void registerBadIndex(IndexId iid, String host){ |
279 | 286 | deadHosts.add(new SearchHost(iid,host)); |
280 | 287 | String key = makeKey(iid,host); |
281 | | - if(remoteKeys.get(key)!=null) |
| 288 | + if(remoteKeys.get(iid.toString())!=null) |
282 | 289 | remoteKeys.get(iid.toString()).remove(key); |
283 | 290 | } |
284 | 291 | |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/search/UpdateThread.java |
— | — | @@ -26,6 +26,7 @@ |
27 | 27 | import org.wikimedia.lsearch.index.WikiSimilarity; |
28 | 28 | import org.wikimedia.lsearch.interoperability.RMIMessengerClient; |
29 | 29 | import org.wikimedia.lsearch.interoperability.RMIServer; |
| 30 | +import org.wikimedia.lsearch.util.Command; |
30 | 31 | |
31 | 32 | |
32 | 33 | /** |
— | — | @@ -77,8 +78,9 @@ |
78 | 79 | protected SearcherCache cache; |
79 | 80 | protected long delayInterval; |
80 | 81 | /** Pending updates, dbrole -> timestamp */ |
81 | | - protected Hashtable<String,Long> pending = new Hashtable<String,Long>(); |
82 | | - |
| 82 | + protected Hashtable<String,Long> pending = new Hashtable<String,Long>(); |
| 83 | + /** Bad indexes at indexer, prevent infinite rsync attempts */ |
| 84 | + protected Hashtable<String,Long> badIndexes = new Hashtable<String,Long>(); |
83 | 85 | protected static UpdateThread instance = null; |
84 | 86 | |
85 | 87 | @Override |
— | — | @@ -143,8 +145,11 @@ |
144 | 146 | |
145 | 147 | /** Rsync a remote snapshot to a local one, updates registry, cache */ |
146 | 148 | protected void rebuild(LocalIndex li){ |
| 149 | + // check if index has previously failed |
| 150 | + if(badIndexes.containsKey(li.iid.toString()) && badIndexes.get(li.iid.toString()).equals(li.timestamp)) |
| 151 | + return; |
| 152 | + |
147 | 153 | final String sep = Configuration.PATH_SEP; |
148 | | - String command; |
149 | 154 | IndexId iid = li.iid; |
150 | 155 | // update path: updatepath/timestamp |
151 | 156 | String updatepath = iid.getUpdatePath(); |
— | — | @@ -171,9 +176,7 @@ |
172 | 177 | try{ |
173 | 178 | // if local, use cp -lr instead of rsync |
174 | 179 | if(global.isLocalhost(iid.getIndexHost())){ |
175 | | - command = "/bin/cp -lr "+iid.getSnapshotPath()+sep+li.timestamp+" "+iid.getUpdatePath(); |
176 | | - log.debug("Running shell command: "+command); |
177 | | - Runtime.getRuntime().exec(command).waitFor(); |
| 180 | + Command.exec("/bin/cp -lr "+iid.getSnapshotPath()+sep+li.timestamp+" "+iid.getUpdatePath()); |
178 | 181 | } else{ |
179 | 182 | File ind = new File(iid.getCanonicalSearchPath()); |
180 | 183 | |
— | — | @@ -181,23 +184,14 @@ |
182 | 185 | ind = ind.getCanonicalFile(); |
183 | 186 | for(File f: ind.listFiles()){ |
184 | 187 | // a cp -lr command for each file in the index |
185 | | - command = "/bin/cp -lr "+ind.getCanonicalPath()+sep+f.getName()+" "+updatepath+sep+f.getName(); |
186 | | - try { |
187 | | - log.debug("Running shell command: "+command); |
188 | | - Runtime.getRuntime().exec(command).waitFor(); |
189 | | - } catch (Exception e) { |
190 | | - log.error("Error making update hardlinked copy "+updatepath+": "+e.getMessage()); |
191 | | - continue; |
192 | | - } |
| 188 | + Command.exec("/bin/cp -lr "+ind.getCanonicalPath()+sep+f.getName()+" "+updatepath+sep+f.getName()); |
193 | 189 | } |
194 | 190 | } |
195 | 191 | long startTime = System.currentTimeMillis(); |
196 | 192 | // rsync |
197 | 193 | log.info("Starting rsync of "+iid); |
198 | 194 | String snapshotpath = iid.getRsyncSnapshotPath()+"/"+li.timestamp; |
199 | | - command = "/usr/bin/rsync -W --delete -r rsync://"+iid.getIndexHost()+":"+snapshotpath+" "+iid.getUpdatePath(); |
200 | | - log.debug("Running shell command: "+command); |
201 | | - Runtime.getRuntime().exec(command).waitFor(); |
| 195 | + Command.exec("/usr/bin/rsync -W --delete -r rsync://"+iid.getIndexHost()+snapshotpath+" "+iid.getUpdatePath()); |
202 | 196 | log.info("Finished rsync of "+iid+" in "+(System.currentTimeMillis()-startTime)+" ms"); |
203 | 197 | |
204 | 198 | } |
— | — | @@ -211,12 +205,8 @@ |
212 | 206 | SearcherCache.SearcherPool pool = new SearcherCache.SearcherPool(iid,li.path,cache.getSearchPoolSize()); |
213 | 207 | |
214 | 208 | // refresh the symlink |
215 | | - command = "/bin/rm -rf "+iid.getSearchPath(); |
216 | | - log.debug("Running shell command: "+command); |
217 | | - Runtime.getRuntime().exec(command).waitFor(); |
218 | | - command = "/bin/ln -fs "+updatepath+" "+iid.getSearchPath(); |
219 | | - log.debug("Running shell command: "+command); |
220 | | - Runtime.getRuntime().exec(command).waitFor(); |
| 209 | + Command.exec("/bin/rm -rf "+iid.getSearchPath()); |
| 210 | + Command.exec("/bin/ln -fs "+updatepath+" "+iid.getSearchPath()); |
221 | 211 | |
222 | 212 | // update registry, cache, rmi object |
223 | 213 | registry.refreshUpdates(iid); |
— | — | @@ -228,9 +218,8 @@ |
229 | 219 | messenger.notifyIndexUpdated(iid,iid.getDBSearchHosts()); |
230 | 220 | |
231 | 221 | } catch(IOException ioe){ |
232 | | - log.error("I/O error on index "+iid+" at "+li.path); |
233 | | - } catch (InterruptedException e) { |
234 | | - log.error("Failed to complete rsync of: "+updatepath); |
| 222 | + log.error("I/O error updating index "+iid+" at "+li.path+" : "+ioe.getMessage()); |
| 223 | + badIndexes.put(li.iid.toString(),li.timestamp); |
235 | 224 | } |
236 | 225 | } |
237 | 226 | |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/search/SearchEngine.java |
— | — | @@ -164,8 +164,7 @@ |
165 | 165 | q = parser.parseFourPass(searchterm,WikiQueryParser.NamespacePolicy.IGNORE,iid.getDBname()); |
166 | 166 | log.info("Using NamespaceFilterWrapper "+nsfw); |
167 | 167 | } |
168 | | - |
169 | | - WikiSearcher searcher = new WikiSearcher(iid); |
| 168 | + |
170 | 169 | TopDocs hits=null; |
171 | 170 | // see if we can search only part of the index |
172 | 171 | if(nsfw!=null && (iid.isMainPart() || iid.isNssplit())){ |
— | — | @@ -182,7 +181,14 @@ |
183 | 182 | } |
184 | 183 | if(part!=null){ |
185 | 184 | IndexId piid = IndexId.get(part); |
186 | | - String host = searcher.getHost(piid); |
| 185 | + String host; |
| 186 | + if(piid.isMySearch()) |
| 187 | + host = "localhost"; |
| 188 | + else{ |
| 189 | + // load balance remote hosts |
| 190 | + WikiSearcher searcher = new WikiSearcher(iid); |
| 191 | + host = searcher.getHost(piid); |
| 192 | + } |
187 | 193 | if(host == null){ |
188 | 194 | res = new SearchResults(); |
189 | 195 | res.setErrorMsg("Error contacting searcher for "+part); |
— | — | @@ -193,6 +199,7 @@ |
194 | 200 | return messenger.searchPart(piid,searchterm,q,nsfw,offset,limit,explain,host); |
195 | 201 | } |
196 | 202 | } |
| 203 | + WikiSearcher searcher = new WikiSearcher(iid); |
197 | 204 | // normal search |
198 | 205 | try{ |
199 | 206 | hits = searcher.search(q,nsfw,offset+limit); |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/index/IndexThread.java |
— | — | @@ -37,6 +37,7 @@ |
38 | 38 | import org.wikimedia.lsearch.config.IndexId; |
39 | 39 | import org.wikimedia.lsearch.config.IndexRegistry; |
40 | 40 | import org.wikimedia.lsearch.interoperability.RMIMessengerClient; |
| 41 | +import org.wikimedia.lsearch.util.Command; |
41 | 42 | |
42 | 43 | /** |
43 | 44 | * Indexer. |
— | — | @@ -266,11 +267,15 @@ |
267 | 268 | indexes.add(iid); |
268 | 269 | } |
269 | 270 | for( IndexId iid : indexes ){ |
270 | | - if(iid.isLogical()) |
271 | | - continue; |
272 | | - optimizeIndex(iid); |
273 | | - makeIndexSnapshot(iid,iid.getIndexPath()); |
274 | | - registry.refreshSnapshots(iid); |
| 271 | + try{ |
| 272 | + if(iid.isLogical()) |
| 273 | + continue; |
| 274 | + optimizeIndex(iid); |
| 275 | + makeIndexSnapshot(iid,iid.getIndexPath()); |
| 276 | + registry.refreshSnapshots(iid); |
| 277 | + } catch(IOException e){ |
| 278 | + log.error("Could not make snapshot for index "+iid); |
| 279 | + } |
275 | 280 | } |
276 | 281 | } |
277 | 282 | |
— | — | @@ -298,13 +303,9 @@ |
299 | 304 | File ind =new File(indexPath); |
300 | 305 | for(File f: ind.listFiles()){ |
301 | 306 | // use a cp -lr command for each file in the index |
302 | | - String command = "/bin/cp -lr "+indexPath+sep+f.getName()+" "+snapshot+sep+f.getName(); |
303 | | - Process copy; |
304 | 307 | try { |
305 | | - log.debug("Running shell command: "+command); |
306 | | - copy = Runtime.getRuntime().exec(command); |
307 | | - copy.waitFor(); |
308 | | - } catch (Exception e) { |
| 308 | + Command.exec("/bin/cp -lr "+indexPath+sep+f.getName()+" "+snapshot+sep+f.getName()); |
| 309 | + } catch (IOException e) { |
309 | 310 | log.error("Error making snapshot "+snapshot+": "+e.getMessage()); |
310 | 311 | continue; |
311 | 312 | } |
— | — | @@ -312,13 +313,14 @@ |
313 | 314 | log.info("Made snapshot "+snapshot); |
314 | 315 | } |
315 | 316 | |
316 | | - /** Optimizes index if needed */ |
317 | | - protected static void optimizeIndex(IndexId iid){ |
| 317 | + /** Optimizes index if needed |
| 318 | + * @throws IOException */ |
| 319 | + protected static void optimizeIndex(IndexId iid) throws IOException{ |
318 | 320 | if(iid.isLogical()) |
319 | 321 | return; |
320 | 322 | if(iid.getBooleanParam("optimize",true)){ |
321 | 323 | try { |
322 | | - IndexReader reader = IndexReader.open(iid.getImportPath()); |
| 324 | + IndexReader reader = IndexReader.open(iid.getIndexPath()); |
323 | 325 | if(!reader.isOptimized()){ |
324 | 326 | reader.close(); |
325 | 327 | log.info("Optimizing "+iid); |
— | — | @@ -334,7 +336,8 @@ |
335 | 337 | } else |
336 | 338 | reader.close(); |
337 | 339 | } catch (IOException e) { |
338 | | - log.error("Could not optimize index at "+iid.getIndexPath()); |
| 340 | + log.error("Could not optimize index at "+iid.getIndexPath()+" : "+e.getMessage()); |
| 341 | + throw e; |
339 | 342 | } |
340 | 343 | } |
341 | 344 | } |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/index/Transaction.java |
— | — | @@ -9,6 +9,7 @@ |
10 | 10 | import org.apache.log4j.Logger; |
11 | 11 | import org.wikimedia.lsearch.config.Configuration; |
12 | 12 | import org.wikimedia.lsearch.config.IndexId; |
| 13 | +import org.wikimedia.lsearch.util.Command; |
13 | 14 | |
14 | 15 | /** |
15 | 16 | * Simple transaction support for indexing. Wrap index operations by |
— | — | @@ -100,9 +101,15 @@ |
101 | 102 | |
102 | 103 | protected int exec(String command) throws Exception { |
103 | 104 | log.debug("Running shell command: "+command); |
104 | | - Process p = Runtime.getRuntime().exec(command); |
105 | | - p.waitFor(); |
106 | | - return p.exitValue(); |
| 105 | + Process p = null; |
| 106 | + try{ |
| 107 | + p = Runtime.getRuntime().exec(command); |
| 108 | + p.waitFor(); |
| 109 | + int exitValue = p.exitValue(); |
| 110 | + return exitValue; |
| 111 | + } finally { |
| 112 | + Command.closeStreams(p); |
| 113 | + } |
107 | 114 | } |
108 | 115 | |
109 | 116 | /** |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/index/WikiIndexModifier.java |
— | — | @@ -373,24 +373,8 @@ |
374 | 374 | return succ; |
375 | 375 | } |
376 | 376 | |
377 | | - /** Close all IndexModifier instances, and optimize if needed */ |
| 377 | + /** Close all IndexModifier instances */ |
378 | 378 | public synchronized static HashSet<IndexId> closeAllModifiers(){ |
379 | | - for(IndexId iid : modifiedDBs){ |
380 | | - if(iid.isLogical()) continue; |
381 | | - if(iid.getBooleanParam("optimize",true)){ |
382 | | - try { |
383 | | - log.debug("Optimizing "+iid); |
384 | | - long start = System.currentTimeMillis(); |
385 | | - IndexWriter writer = new IndexWriter(iid.getIndexPath(),new SimpleAnalyzer(),false); |
386 | | - writer.optimize(); |
387 | | - writer.close(); |
388 | | - long delta = System.currentTimeMillis() - start; |
389 | | - log.info("Optimized "+iid+" in "+delta+" ms"); |
390 | | - } catch (IOException e) { |
391 | | - log.error("Could not optimize index at "+iid.getIndexPath()); |
392 | | - } |
393 | | - } |
394 | | - } |
395 | 379 | HashSet<IndexId> retVal = modifiedDBs; |
396 | 380 | modifiedDBs = new HashSet<IndexId>(); |
397 | 381 | return retVal; |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/analyzers/WikiQueryParser.java |
— | — | @@ -79,7 +79,7 @@ |
80 | 80 | public static float TITLE_ALIAS_BOOST = 0.2f; |
81 | 81 | public static float STEM_TITLE_BOOST = 2; |
82 | 82 | public static float STEM_TITLE_ALIAS_BOOST = 0.4f; |
83 | | - public static float ALT_TITLE_BOOST = 2; |
| 83 | + public static float ALT_TITLE_BOOST = 4; |
84 | 84 | public static float ALT_TITLE_ALIAS_BOOST = 0.4f; |
85 | 85 | public static float KEYWORD_BOOST = 0.02f; |
86 | 86 | |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/oai/IncrementalUpdater.java |
— | — | @@ -179,8 +179,16 @@ |
180 | 180 | boolean hasMore = false; |
181 | 181 | do{ |
182 | 182 | if(fetchReferences){ |
183 | | - // fetch references for records |
184 | | - fetchReferences(records,dbname); |
| 183 | + try{ |
| 184 | + // fetch references for records |
| 185 | + fetchReferences(records,dbname); |
| 186 | + } catch(IOException e){ |
| 187 | + // FIXME: quick hack, if the table cannot be found (e.g. for new wikis) don't abort |
| 188 | + if(e.getMessage().contains("Base table or view not found")){ |
| 189 | + log.warn("Continuing, but could not fetch references for "+iid+": "+e.getMessage()); |
| 190 | + } else |
| 191 | + throw e; |
| 192 | + } |
185 | 193 | } |
186 | 194 | for(IndexUpdateRecord rec : records){ |
187 | 195 | Article ar = rec.getArticle(); |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/util/Localization.java |
— | — | @@ -157,7 +157,7 @@ |
158 | 158 | } |
159 | 159 | } |
160 | 160 | } catch (Exception e) { |
161 | | - log.warn("Error processing message file at "+MessageFormat.format(loc,langCode)); |
| 161 | + log.warn("Error processing message file at "+MessageFormat.format(loc+"Messages{0}.php",langCode)); |
162 | 162 | } |
163 | 163 | log.warn("Could not load localization for "+langCode); |
164 | 164 | badLocalizations.add(langCode.toLowerCase()); |
Index: trunk/lucene-search-2.0/src/org/wikimedia/lsearch/util/Command.java |
— | — | @@ -0,0 +1,49 @@ |
| 2 | +package org.wikimedia.lsearch.util; |
| 3 | + |
| 4 | +import java.io.BufferedReader; |
| 5 | +import java.io.IOException; |
| 6 | +import java.io.InputStreamReader; |
| 7 | + |
| 8 | +import org.apache.log4j.Logger; |
| 9 | + |
| 10 | +/** |
| 11 | + * Send a command to OS, handle errors, and properly close streams |
| 12 | + * |
| 13 | + * @author rainman |
| 14 | + * |
| 15 | + */ |
| 16 | +public class Command { |
| 17 | + static Logger log = Logger.getLogger(Command.class); |
| 18 | + |
| 19 | + public static void closeStreams(Process p) throws IOException { |
| 20 | + if(p != null){ |
| 21 | + p.getInputStream().close(); |
| 22 | + p.getOutputStream().close(); |
| 23 | + p.getErrorStream().close(); |
| 24 | + } |
| 25 | + } |
| 26 | + |
| 27 | + public static void exec(String command) throws IOException { |
| 28 | + Process p = null; |
| 29 | + log.debug("Executing shell command "+command); |
| 30 | + try { |
| 31 | + p = Runtime.getRuntime().exec(command); |
| 32 | + p.waitFor(); |
| 33 | + if(p.exitValue()!=0){ |
| 34 | + log.warn("Got exit value "+p.exitValue()+" while executing "+command); |
| 35 | + String line; |
| 36 | + StringBuilder sb = new StringBuilder(); |
| 37 | + BufferedReader r = new BufferedReader(new InputStreamReader(p.getErrorStream())); |
| 38 | + while((line = r.readLine()) != null) |
| 39 | + sb.append(line); |
| 40 | + throw new IOException("Error executing command: "+sb); |
| 41 | + } |
| 42 | + } catch (InterruptedException e) { |
| 43 | + e.printStackTrace(); |
| 44 | + throw new IOException("Interrupted"); |
| 45 | + } finally { |
| 46 | + closeStreams(p); |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | +} |
Index: trunk/lucene-search-2.0/build.xml |
— | — | @@ -8,8 +8,8 @@ |
9 | 9 | <property name="pack.name" value="lucene-search-2.0"/> |
10 | 10 | <property name="binary.name" value="ls2-bin"/> |
11 | 11 | <property name="jar.name" value="LuceneSearch.jar"/> |
| 12 | + <property name="include" value="src/** lib/** sql/** test-data/** webinterface/** *-example *.txt lsearch* build.xml scripts/*"/> |
12 | 13 | |
13 | | - |
14 | 14 | <property file="${basedir}/hostname"/> |
15 | 15 | |
16 | 16 | <path id="classpath"> |
— | — | @@ -65,27 +65,29 @@ |
66 | 66 | |
67 | 67 | <target name="build" description="Compile classes"> |
68 | 68 | <mkdir dir="${bin}"/> |
69 | | - <javac srcdir="${src}/org/" debug="on" includes="**/*.java" destdir="${bin}/"> |
| 69 | + <javac srcdir="${src}/org/" debug="on" encoding="UTF-8" includes="**/*.java" destdir="${bin}/"> |
70 | 70 | <classpath refid="classpath"/> |
71 | 71 | </javac> |
72 | 72 | </target> |
73 | 73 | |
74 | 74 | <target name="pack" description="Make tar.gz distribution"> |
| 75 | + <mkdir dir="${dist}"/> |
75 | 76 | <delete file="${dist}/${pack.name}.tar"/> |
76 | 77 | <delete file="${dist}/${pack.name}.tar.gz"/> |
77 | 78 | <tar tarfile="${dist}/${pack.name}.tar"> |
78 | | - <tarfileset prefix="${pack.name}" dir="." includes="**/*" excludes="dist/ bin/ ${jar.name}"/> |
| 79 | + <tarfileset prefix="${pack.name}" dir="." includes="${include}"/> |
79 | 80 | </tar> |
80 | 81 | |
81 | 82 | <gzip zipfile="${dist}/${pack.name}.tar.gz" src="${dist}/${pack.name}.tar"/> |
82 | 83 | <delete file="${dist}/${pack.name}.tar"/> |
83 | 84 | </target> |
84 | 85 | |
85 | | - <target name="binary" depends="makejar" description="Make binary tar.gz distribution"> |
| 86 | + <target name="binary" depends="alljar" description="Make binary tar.gz distribution"> |
| 87 | + <mkdir dir="${bin}"/> |
86 | 88 | <delete file="${dist}/${binary.name}.tar"/> |
87 | 89 | <delete file="${dist}/${binary.name}.tar.gz"/> |
88 | 90 | <tar tarfile="${dist}/${binary.name}.tar"> |
89 | | - <tarfileset prefix="${binary.name}" dir="." includes="**/*" excludes="dist/ doc/ src/ test-data/ bin/ TODO .svn **/.svn"/> |
| 91 | + <tarfileset prefix="${binary.name}" dir="." includes="${jar.name} ${include}" excludes="src/ test-data/ lib/*.jar"/> |
90 | 92 | </tar> |
91 | 93 | |
92 | 94 | <gzip zipfile="${dist}/${binary.name}.tar.gz" src="${dist}/${binary.name}.tar"/> |
Index: trunk/lucene-search-2.0/lsearch.conf |
— | — | @@ -1,4 +1,4 @@ |
2 | | -# By default, will check /etc/mwsearch.conf |
| 2 | +# By default, will check /etc/lsearch.conf |
3 | 3 | |
4 | 4 | ################################################ |
5 | 5 | # Global configuration |