public HsErrPidList() { if (Functions.getIsUnitTest()) { return; } try { FileChannel ch = new FileInputStream(getSecretKeyFile()).getChannel(); map = ch.map(MapMode.READ_ONLY, 0, 1); scan("./hs_err_pid%p.log"); if (Functions.isWindows()) { File dir = Kernel32Utils.getTempDir(); if (dir != null) { scan(dir.getPath() + "\\hs_err_pid%p.log"); } } else { scan("/tmp/hs_err_pid%p.log"); } // on different platforms, rules about the default locations are a lot more subtle. // check our arguments in the very end since this might fail on some platforms JavaVMArguments args = JavaVMArguments.current(); for (String a : args) { // see http://www.oracle.com/technetwork/java/javase/felog-138657.html if (a.startsWith(ERROR_FILE_OPTION)) { scan(a.substring(ERROR_FILE_OPTION.length())); } } } catch (UnsupportedOperationException e) { // ignore } catch (Throwable e) { LOGGER.log(Level.WARNING, "Failed to list up hs_err_pid files", e); } }
{ StaplerRequest req = Stapler.getCurrentRequest(); iconSize = req != null ? Functions.validateIconSize(Functions.getCookie(req, "iconSize", "32x32")) : "32x32"; }
/** Expect errors from {@link org.codehaus.groovy.runtime.NullObject}. */ @Issue("kohsuke/groovy-sandbox #15") @Test public void nullPointerException() throws Exception { try { assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member"); } catch (NullPointerException x) { assertEquals( Functions.printThrowable(x), "Cannot get property 'member' on null object", x.getMessage()); } try { assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member = 42"); } catch (NullPointerException x) { assertEquals( Functions.printThrowable(x), "Cannot set property 'member' on null object", x.getMessage()); } try { assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member()"); } catch (NullPointerException x) { assertEquals( Functions.printThrowable(x), "Cannot invoke method member() on null object", x.getMessage()); } }
public Map<String, String> call() { Map<String, String> r = new LinkedHashMap<String, String>(); ThreadInfo[] data = Functions.getThreadInfos(); Functions.ThreadGroupMap map = Functions.sortThreadsAndGetGroupMap(data); for (ThreadInfo ti : data) r.put(ti.getThreadName(), Functions.dumpThreadInfo(ti, map)); return r; }
public ContextMenu add(Action a) { StaplerRequest req = Stapler.getCurrentRequest(); String text = a.getDisplayName(); String base = Functions.getIconFilePath(a); if (base == null) return this; String icon = Stapler.getCurrentRequest().getContextPath() + (base.startsWith("images/") ? Functions.getResourcePath() : "") + '/' + base; String url = Functions.getActionUrl(req.findAncestor(ModelObject.class).getUrl(), a); return add(url, icon, text); }
@Extension public static DescriptorImpl install() { if (!Functions.isWindows()) { return new DescriptorImpl(); } return null; }
public void testSymlink() throws Exception { if (Functions.isWindows()) return; ByteArrayOutputStream baos = new ByteArrayOutputStream(); StreamTaskListener l = new StreamTaskListener(baos); File d = Util.createTempDir(); try { new FilePath(new File(d, "a")).touch(0); Util.createSymlink(d, "a", "x", l); assertEquals("a", Util.resolveSymlink(new File(d, "x"), l)); // test a long name StringBuilder buf = new StringBuilder(768); for (int i = 0; i < 768; i++) buf.append('0' + (i % 10)); Util.createSymlink(d, buf.toString(), "x", l); String log = baos.toString(); if (log.length() > 0) { System.err.println("log output: " + log); if (log.contains("ln failed: 78" /*ENAMETOOLONG*/)) { buf.setLength(0); // Try again with shorter name for this system for (int i = 0; i < 254; i++) buf.append('0' + (i % 10)); Util.createSymlink(d, buf.toString(), "x", l); } } assertEquals(buf.toString(), Util.resolveSymlink(new File(d, "x"), l)); } finally { Util.deleteRecursive(d); } }
@Override protected synchronized JSON data() { JSONArray r = new JSONArray(); for (User u : modified) { UserInfo i = users.get(u); JSONObject entry = new JSONObject() .accumulate("id", u.getId()) .accumulate("fullName", u.getFullName()) .accumulate("url", u.getUrl()) .accumulate( "avatar", i.avatar != null ? i.avatar : Stapler.getCurrentRequest().getContextPath() + Functions.getResourcePath() + "/images/" + iconSize + "/user.png") .accumulate("timeSortKey", i.getTimeSortKey()) .accumulate("lastChangeTimeString", i.getLastChangeTimeString()); AbstractProject<?, ?> p = i.getProject(); if (p != null) { entry .accumulate("projectUrl", p.getUrl()) .accumulate("projectFullDisplayName", p.getFullDisplayName()); } r.add(entry); } modified.clear(); return r; }
/** Fake installation on Unix. */ @Test public void fakeUnixInstall() throws Exception { Assume.assumeFalse("If we're on Windows, don't bother doing this", Functions.isWindows()); File bundle = File.createTempFile("fake-jdk-by-hudson", "sh"); try { new FilePath(bundle) .write( "#!/bin/bash -ex\n" + "mkdir -p jdk1.6.0_dummy/bin\n" + "touch jdk1.6.0_dummy/bin/java", "ASCII"); TaskListener l = StreamTaskListener.fromStdout(); new JDKInstaller("", true) .install( new LocalLauncher(l), Platform.LINUX, new JDKInstaller.FilePathFileSystem(j.jenkins), l, tmp.getRoot().getPath(), bundle.getPath()); assertTrue(new File(tmp.getRoot(), "bin/java").exists()); } finally { bundle.delete(); } }
@Issue("JENKINS-30941") @Test public void cleanUpSucceeds() throws Exception { /** Issue was just present on Linux not windows - but the test will run on both */ final String credentialsId = "zipfile"; /* do the dance to get a simple zip file into jenkins */ InputStream zipStream = this.getClass().getResourceAsStream("a.zip"); try { assertThat(zipStream, is(not(nullValue()))); File zip = tmp.newFile("a.zip"); FileUtils.copyInputStreamToFile(zipStream, zip); FileItem fi = new FileItemImpl(zip); FileCredentialsImpl fc = new FileCredentialsImpl( CredentialsScope.GLOBAL, credentialsId, "Just a zip file", fi, fi.getName(), null); CredentialsProvider.lookupStores(j.jenkins) .iterator() .next() .addCredentials(Domain.global(), fc); } finally { IOUtils.closeQuietly(zipStream); zipStream = null; } final String unixFile = "/dir/testfile.txt"; final String winFile = unixFile.replace( "/", "\\\\"); /* two \\ as we escape the code and then escape for the script */ // if this file does not have a line ending then the text is not echoed to the log. // fixed in workflow 1.11+ (which is not released at the time of writing) final String contents = "Test of ZipFileBinding\n"; WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition( new CpsFlowDefinition( "" + "node {\n" + " withCredentials([[$class: 'ZipFileBinding', credentialsId: '" + credentialsId + "', variable: 'ziploc']]) {\n" + (Functions.isWindows() ? " bat 'type %ziploc%" + winFile + "'\n" : " sh 'cat ${ziploc}" + unixFile + "'\n") + " def text = readFile encoding: 'UTF-8', file: \"${env.ziploc}" + unixFile + "\"\n" + " if (!text.equals('''" + contents + "''')) {\n" + " error ('incorrect details from zip file')\n" + " }\n" + " }\n" + "}\n", true)); WorkflowRun run = p.scheduleBuild2(0).get(); j.assertBuildStatusSuccess(run); j.assertLogContains(contents, run); }
/** @return configured dot executable or a default */ public String getDotExeOrDefault() { if (Util.fixEmptyAndTrim(dotExe) == null) { return Functions.isWindows() ? "dot.exe" : "dot"; } else { return dotExe; } }
@Test public void deleteFile() throws Exception { Assume.assumeTrue(Functions.isWindows()); Class<?> c; try { c = Class.forName("java.nio.file.FileSystemException"); } catch (ClassNotFoundException x) { throw new AssumptionViolatedException("prior to JDK 7", x); } File d = Util.createTempDir(); try { File f = new File(d, "f"); OutputStream os = new FileOutputStream(f); try { Util.deleteFile(f); fail("should not have been deletable"); } catch (IOException x) { assertEquals(c, x.getClass()); } finally { os.close(); } } finally { Util.deleteRecursive(d); } }
@Test public void testIsSymlink() throws IOException, InterruptedException { Assume.assumeTrue(!Functions.isWindows()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); StreamTaskListener l = new StreamTaskListener(baos); File d = Util.createTempDir(); try { new FilePath(new File(d, "original")).touch(0); assertFalse(Util.isSymlink(new File(d, "original"))); Util.createSymlink(d, "original", "link", l); assertTrue(Util.isSymlink(new File(d, "link"))); // test linking to another directory File dir = new File(d, "dir"); assertTrue("Couldn't create " + dir, dir.mkdir()); assertFalse(Util.isSymlink(new File(d, "dir"))); File anotherDir = new File(d, "anotherDir"); assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir()); Util.createSymlink(d, "dir", "anotherDir/symlinkDir", l); // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work: // assertTrue(Util.isSymlink(new File(d,"anotherDir/symlinkDir"))); } finally { Util.deleteRecursive(d); } }
@Restricted(DoNotUse.class) // accessed via REST API public HttpResponse doGenerateSnippet(StaplerRequest req, @QueryParameter String json) throws Exception { // TODO JENKINS-31458 is there not an easier way to do this? JSONObject jsonO = JSONObject.fromObject(json); Jenkins j = Jenkins.getActiveInstance(); Class<?> c = j.getPluginManager().uberClassLoader.loadClass(jsonO.getString("stapler-class")); StepDescriptor descriptor = (StepDescriptor) j.getDescriptor(c.asSubclass(Step.class)); Object o; try { o = descriptor.newInstance(req, jsonO); } catch (RuntimeException x) { // e.g. IllegalArgumentException return HttpResponses.plainText(Functions.printThrowable(x)); } try { String groovy = object2Groovy(o); if (descriptor.isAdvanced()) { String warning = Messages.Snippetizer_this_step_should_not_normally_be_used_in(); groovy = "// " + warning + "\n" + groovy; } return HttpResponses.plainText(groovy); } catch (UnsupportedOperationException x) { Logger.getLogger(CpsFlowExecution.class.getName()) .log(Level.WARNING, "failed to render " + json, x); return HttpResponses.plainText(x.getMessage()); } }
@Override public Publisher newInstance(StaplerRequest req, JSONObject formData) { Mailer m = new Mailer(); req.bindParameters(m, "mailer_"); m.dontNotifyEveryUnstableBuild = req.getParameter("mailer_notifyEveryUnstableBuild") == null; if (hudsonUrl == null) { // if Hudson URL is not configured yet, infer some default hudsonUrl = Functions.inferHudsonURL(req); save(); } return m; }
public final String getUrl() { // try to stick to the current view if possible StaplerRequest req = Stapler.getCurrentRequest(); if (req != null) { String seed = Functions.getNearestAncestorUrl(req,this); if(seed!=null) { // trim off the context path portion and leading '/', but add trailing '/' return seed.substring(req.getContextPath().length()+1)+'/'; } } // otherwise compute the path normally return getParent().getUrl()+getShortUrl(); }
/** * If true, we can do ADSI/COM based look up that's far more reliable. False if we need to do * the authentication in pure Java via {@link ActiveDirectoryUnixAuthenticationProvider} */ public boolean canDoNativeAuth() { if (!Functions.isWindows()) return false; try { ClassFactory.createConnection().dispose(); return true; } catch (Throwable t) { if (!WARNED) { LOGGER.log( Level.INFO, "COM4J isn't working. Falling back to non-native authentication", t); WARNED = true; } return false; } }
private static void expectRejection( MatrixProject project, String combinationFilter, String signature) throws IOException { ScriptApproval scriptApproval = ScriptApproval.get(); assertEquals(Collections.emptySet(), scriptApproval.getPendingSignatures()); try { project.setCombinationFilter(combinationFilter); } catch (RejectedAccessException x) { assertEquals(Functions.printThrowable(x), signature, x.getSignature()); } Set<ScriptApproval.PendingSignature> pendingSignatures = scriptApproval.getPendingSignatures(); assertEquals(1, pendingSignatures.size()); assertEquals(signature, pendingSignatures.iterator().next().signature); scriptApproval.approveSignature(signature); assertEquals(Collections.emptySet(), scriptApproval.getPendingSignatures()); }
@Bug(22641) public void testProcessProperlyKilledUnix() throws Exception { ProcessTree.enabled = true; if (Functions.isWindows()) return; // This test does not involve windows. FreeStyleProject sleepProject = createFreeStyleProject(); FreeStyleProject processJob = createFreeStyleProject(); sleepProject.getBuildersList().add(new Shell("nohup sleep 100000 &")); assertBuildStatusSuccess(sleepProject.scheduleBuild2(0).get()); processJob.getBuildersList().add(new Shell("ps -ef | grep sleep")); assertLogNotContains("sleep 100000", processJob.scheduleBuild2(0).get()); }
@Test public void testSymlink() throws Exception { Assume.assumeTrue(!Functions.isWindows()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); StreamTaskListener l = new StreamTaskListener(baos); File d = Util.createTempDir(); try { new FilePath(new File(d, "a")).touch(0); assertNull(Util.resolveSymlink(new File(d, "a"))); Util.createSymlink(d, "a", "x", l); assertEquals("a", Util.resolveSymlink(new File(d, "x"))); // test a long name StringBuilder buf = new StringBuilder(768); for (int i = 0; i < 768; i++) buf.append((char) ('0' + (i % 10))); Util.createSymlink(d, buf.toString(), "x", l); String log = baos.toString(); if (log.length() > 0) System.err.println("log output: " + log); assertEquals(buf.toString(), Util.resolveSymlink(new File(d, "x"))); // test linking from another directory File anotherDir = new File(d, "anotherDir"); assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir()); Util.createSymlink(d, "a", "anotherDir/link", l); assertEquals("a", Util.resolveSymlink(new File(d, "anotherDir/link"))); // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work: // assertTrue(Util.isSymlink(new File(d,"anotherDir/link"))); File external = File.createTempFile("something", ""); try { Util.createSymlink(d, external.getAbsolutePath(), "outside", l); assertEquals(external.getAbsolutePath(), Util.resolveSymlink(new File(d, "outside"))); } finally { assertTrue(external.delete()); } } finally { Util.deleteRecursive(d); } }
/** * Gets the {@link User} object by its id or full name. * * @param create If true, this method will never return null for valid input (by creating a new * {@link User} object if none exists.) If false, this method will return null if {@link User} * object with the given name doesn't exist. */ public static User get(String idOrFullName, boolean create) { if (idOrFullName == null) return null; String id = idOrFullName .replace('\\', '_') .replace('/', '_') .replace('<', '_') .replace('>', '_'); // 4 replace() still faster than regex if (Functions.isWindows()) id = id.replace(':', '_'); synchronized (byName) { User u = byName.get(id); if (u == null) { User tmp = new User(id, idOrFullName); if (create || tmp.getConfigFile().exists()) { byName.put(id, u = tmp); } } return u; } }
/** * Send an email to the admin address * * @throws IOException * @throws ServletException * @throws InterruptedException */ public FormValidation doSendTestMail( @QueryParameter String smtpServer, @QueryParameter String adminAddress, @QueryParameter boolean useSMTPAuth, @QueryParameter String smtpAuthUserName, @QueryParameter String smtpAuthPassword, @QueryParameter boolean useSsl, @QueryParameter String smtpPort) throws IOException, ServletException, InterruptedException { try { if (!useSMTPAuth) smtpAuthUserName = smtpAuthPassword = null; MimeMessage msg = new MimeMessage( createSession( smtpServer, smtpPort, useSsl, smtpAuthUserName, Secret.fromString(smtpAuthPassword))); msg.setSubject("Test email #" + ++testEmailCount); msg.setContent( "This is test email #" + testEmailCount + " sent from Hudson Continuous Integration server.", "text/plain"); msg.setFrom(new InternetAddress(adminAddress)); msg.setSentDate(new Date()); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(adminAddress)); Transport.send(msg); return FormValidation.ok("Email was successfully sent"); } catch (MessagingException e) { return FormValidation.errorWithMarkup( "<p>Failed to send out e-mail</p><pre>" + Util.escape(Functions.printThrowable(e)) + "</pre>"); } }
private boolean createSdCard(File homeDir) { // Build command: mksdcard 32M /home/foo/.android/avd/whatever.avd/sdcard.img ArgumentListBuilder builder = Utils.getToolCommand(androidSdk, !Functions.isWindows(), Tool.MKSDCARD, null); builder.add(sdCardSize); builder.add(new File(getAvdDirectory(homeDir), "sdcard.img")); // Run! try { ProcessBuilder procBuilder = new ProcessBuilder(builder.toList()); if (androidSdkHome != null) { procBuilder.environment().put("ANDROID_SDK_HOME", androidSdkHome); } procBuilder.start().waitFor(); } catch (InterruptedException ex) { return false; } catch (IOException ex) { return false; } return true; }
@Override public String getHelpFile() { return Functions.getResourcePath() + "/plugin/android-device/help-buildConfig.html"; }
/** validate the value for a remote (repository) location. */ public FormValidation doCheckCredentialsId( StaplerRequest req, @AncestorInPath SCMSourceOwner context, @QueryParameter String remoteBase, @QueryParameter String value) { // TODO suspiciously similar to // SubversionSCM.ModuleLocation.DescriptorImpl.checkCredentialsId; refactor into shared // method? // Test the connection only if we may use the credentials if (context == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER) || context != null && !context.hasPermission(CredentialsProvider.USE_ITEM)) { return FormValidation.ok(); } // if check remote is reporting an issue then we don't need to String url = Util.fixEmptyAndTrim(remoteBase); if (url == null) return FormValidation.ok(); if (!URL_PATTERN.matcher(url).matches()) return FormValidation.ok(); try { String urlWithoutRevision = SvnHelper.getUrlWithoutRevision(url); SVNURL repoURL = SVNURL.parseURIDecoded(urlWithoutRevision); StandardCredentials credentials = value == null ? null : CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials( StandardCredentials.class, context, ACL.SYSTEM, URIRequirementBuilder.fromUri(repoURL.toString()).build()), CredentialsMatchers.withId(value)); if (checkRepositoryPath(context, repoURL, credentials) != SVNNodeKind.NONE) { // something exists; now check revision if any SVNRevision revision = getRevisionFromRemoteUrl(url); if (revision != null && !revision.isValid()) { return FormValidation.errorWithMarkup( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_invalidRevision()); } return FormValidation.ok(); } SVNRepository repository = null; try { repository = getRepository( context, repoURL, credentials, Collections.<String, Credentials>emptyMap(), null); long rev = repository.getLatestRevision(); // now go back the tree and find if there's anything that exists String repoPath = getRelativePath(repoURL, repository); String p = repoPath; while (p.length() > 0) { p = SVNPathUtil.removeTail(p); if (repository.checkPath(p, rev) == SVNNodeKind.DIR) { // found a matching path List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>(); repository.getDir(p, rev, false, entries); // build up the name list List<String> paths = new ArrayList<String>(); for (SVNDirEntry e : entries) if (e.getKind() == SVNNodeKind.DIR) paths.add(e.getName()); String head = SVNPathUtil.head(repoPath.substring(p.length() + 1)); String candidate = EditDistance.findNearest(head, paths); return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPathSuggest( p, head, candidate != null ? "/" + candidate : "")); } } return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPath(repoPath)); } finally { if (repository != null) repository.closeSession(); } } catch (SVNException e) { LOGGER.log(Level.INFO, "Failed to access subversion repository " + url, e); String message = hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_exceptionMsg1( Util.escape(url), Util.escape(e.getErrorMessage().getFullMessage()), "javascript:document.getElementById('svnerror').style.display='block';" + "document.getElementById('svnerrorlink').style.display='none';" + "return false;") + "<br/><pre id=\"svnerror\" style=\"display:none\">" + Functions.printThrowable(e) + "</pre>"; return FormValidation.errorWithMarkup(message); } }
/** * Used to render the side panel "Back to project" link. * * <p>In a rare situation where a build can be reached from multiple paths, returning different * URLs from this method based on situations might be desirable. * * <p>If you override this method, you'll most likely also want to override {@link * #getDisplayName()}. */ public String getUpUrl() { return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(), getParent()) + '/'; }
public Boolean call() throws AndroidEmulatorException { if (logger == null) { logger = listener.getLogger(); } final File homeDir = Utils.getHomeDirectory(androidSdk.getSdkHome()); final File avdDirectory = getAvdDirectory(homeDir); final boolean emulatorExists = getAvdConfigFile(homeDir).exists(); // Can't do anything if a named emulator doesn't exist if (isNamedEmulator() && !emulatorExists) { throw new EmulatorDiscoveryException(Messages.AVD_DOES_NOT_EXIST(avdName, avdDirectory)); } // Check whether AVD needs to be created boolean createSdCard = false; boolean createSnapshot = false; File snapshotsFile = new File(getAvdDirectory(homeDir), "snapshots.img"); if (emulatorExists) { // AVD exists: check whether there's anything still to be set up File sdCardFile = new File(getAvdDirectory(homeDir), "sdcard.img"); boolean sdCardRequired = getSdCardSize() != null; // Check if anything needs to be done for snapshot-enabled builds if (shouldUseSnapshots() && androidSdk.supportsSnapshots()) { if (!snapshotsFile.exists()) { createSnapshot = true; } // We should ensure that we start out with a clean SD card for the build if (sdCardRequired && sdCardFile.exists()) { sdCardFile.delete(); } } // Flag that we need to generate an SD card, if there isn't one existing if (sdCardRequired && !sdCardFile.exists()) { createSdCard = true; } // If everything is ready, then return if (!createSdCard && !createSnapshot) { return true; } } else { AndroidEmulator.log(logger, Messages.CREATING_AVD(avdDirectory)); } // We can't continue if we don't know where to find emulator images or tools if (!androidSdk.hasKnownRoot()) { throw new EmulatorCreationException(Messages.SDK_NOT_SPECIFIED()); } final File sdkRoot = new File(androidSdk.getSdkRoot()); if (!sdkRoot.exists()) { throw new EmulatorCreationException(Messages.SDK_NOT_FOUND(androidSdk.getSdkRoot())); } // If we need to initialise snapshot support for an existing emulator, do so if (createSnapshot) { // Copy the snapshots file into place File snapshotDir = new File(sdkRoot, "tools/lib/emulator"); Util.copyFile(new File(snapshotDir, "snapshots.img"), snapshotsFile); // Update the AVD config file mark snapshots as enabled Map<String, String> configValues; try { configValues = parseAvdConfigFile(homeDir); configValues.put("snapshot.present", "true"); writeAvdConfigFile(homeDir, configValues); } catch (IOException e) { throw new EmulatorCreationException(Messages.AVD_CONFIG_NOT_READABLE(), e); } } // If we need create an SD card for an existing emulator, do so if (createSdCard) { AndroidEmulator.log(logger, Messages.ADDING_SD_CARD(sdCardSize, getAvdName())); if (!createSdCard(homeDir)) { throw new EmulatorCreationException(Messages.SD_CARD_CREATION_FAILED()); } // Update the AVD config file Map<String, String> configValues; try { configValues = parseAvdConfigFile(homeDir); configValues.put("sdcard.size", sdCardSize); writeAvdConfigFile(homeDir, configValues); } catch (IOException e) { throw new EmulatorCreationException(Messages.AVD_CONFIG_NOT_READABLE(), e); } } // Return if everything is now ready for use if (emulatorExists) { return true; } // Build up basic arguments to `android` command final StringBuilder args = new StringBuilder(100); args.append("create avd "); // Overwrite any existing files args.append("-f "); // Initialise snapshot support, regardless of whether we will actually use it if (androidSdk.supportsSnapshots()) { args.append("-a "); } if (sdCardSize != null) { args.append("-c "); args.append(sdCardSize); args.append(" "); } args.append("-s "); args.append(screenResolution.getSkinName()); args.append(" -n "); args.append(getAvdName()); boolean isUnix = !Functions.isWindows(); ArgumentListBuilder builder = Utils.getToolCommand(androidSdk, isUnix, Tool.ANDROID, args.toString()); // Tack on quoted platform name at the end, since it can be anything builder.add("-t"); builder.add(osVersion.getTargetName()); if (targetAbi != null) { builder.add("--abi"); builder.add(targetAbi); } // Log command line used, for info AndroidEmulator.log(logger, builder.toStringWithQuote()); // Run! boolean avdCreated = false; final Process process; try { ProcessBuilder procBuilder = new ProcessBuilder(builder.toList()); if (androidSdk.hasKnownHome()) { procBuilder.environment().put("ANDROID_SDK_HOME", androidSdk.getSdkHome()); } process = procBuilder.start(); } catch (IOException ex) { throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED()); } // Redirect process's stderr to a stream, for logging purposes ByteArrayOutputStream stderr = new ByteArrayOutputStream(); ByteArrayOutputStream stdout = new ByteArrayOutputStream(); new StreamCopyThread("", process.getErrorStream(), stderr).start(); // Command may prompt us whether we want to further customise the AVD. // Just "press" Enter to continue with the selected target's defaults. try { boolean processAlive = true; // Block until the command outputs something (or process ends) final PushbackInputStream in = new PushbackInputStream(process.getInputStream(), 10); int len = in.read(); if (len == -1) { // Check whether the process has exited badly, as sometimes no output is valid. // e.g. When creating an AVD with Google APIs, no user input is requested. if (process.waitFor() != 0) { AndroidEmulator.log(logger, Messages.AVD_CREATION_FAILED()); AndroidEmulator.log(logger, stderr.toString(), true); throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED()); } processAlive = false; } in.unread(len); // Write CRLF, if required if (processAlive) { final OutputStream stream = process.getOutputStream(); stream.write('\r'); stream.write('\n'); stream.flush(); stream.close(); } // read the rest of stdout (for debugging purposes) Util.copyStream(in, stdout); in.close(); // Wait for happy ending if (process.waitFor() == 0) { // Do a sanity check to ensure the AVD was really created avdCreated = getAvdConfigFile(homeDir).exists(); } } catch (IOException e) { throw new EmulatorCreationException(Messages.AVD_CREATION_ABORTED(), e); } catch (InterruptedException e) { throw new EmulatorCreationException(Messages.AVD_CREATION_INTERRUPTED(), e); } finally { process.destroy(); } // For reasons unknown, the return code may not be correctly reported on Windows. // So check whether stderr contains failure info (useful for other platforms too). String errOutput = stderr.toString(); String output = stdout.toString(); if (errOutput.contains("list targets")) { AndroidEmulator.log(logger, Messages.INVALID_AVD_TARGET(osVersion.getTargetName())); avdCreated = false; errOutput = null; } else if (errOutput.contains("more than one ABI")) { AndroidEmulator.log( logger, Messages.MORE_THAN_ONE_ABI(osVersion.getTargetName(), output), true); avdCreated = false; errOutput = null; } // Check everything went ok if (!avdCreated) { if (errOutput != null && errOutput.length() != 0) { AndroidEmulator.log(logger, stderr.toString(), true); } throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED()); } // Done! return false; }
private void configureDumpEnvBuilder() throws IOException { if (Functions.isWindows()) project.getBuildersList().add(new BatchFile("set")); else project.getBuildersList().add(new Shell("export")); }
public String getShellOrDefault() { if (shell == null) { return Functions.isWindows() ? "sh" : "/bin/sh"; } return shell; }
public String call() throws IOException { return Functions.isWindows() ? "sh" : "/bin/sh"; }