From: <ma...@rh...> - 2009-01-20 18:41:14
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg DL { border : 1px #006 solid; background-color : #369; padding : 6px; color : #fff; } #msg DT { float : left; width : 6em; font-weight : bold; } #msg DL, #msg DT, #msg UL, #msg LI { font-family : arial,helvetica,sans-serif; font-size : 10pt; } h3 { font-family : arial,helvetica,sans-serif; font-size : 10pt; font-weight : bold; } #msg PRE { overflow : auto; white-space : normal; background-color : #ffc; border : 1px #fc0 solid; padding : 6px; } #msg UL, PRE, .diff { overflow : auto; } #patch h4 { font-family : arial,helvetica,sans-serif; font-size : 10pt; } #patch h4 { padding: 8px; background : #369; color : #fff; margin : 0; } #patch .propset h4, #patch .binary h4 {margin: 0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {background:#eeeeee;padding: 0 0 10px 0;} #patch .propset .diff, #patch .binary .diff {padding: 10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch .add {background:#ddffdd;} #patch .rem {background:#ffdddd;} #patch .lines, .info {color:#888888;background:#ffffff;} .diff { width : 100%; } #msg DL { border : 1px #006 solid; background-color : #369; padding : 6px; color : #fff; } #msg DT { float : left; width : 6em; font-weight : bold; } #msg DL, #msg DT, #msg UL, #msg LI { font-family : arial,helvetica,sans-serif; font-size : 10pt; } h3 { font-family : arial,helvetica,sans-serif; font-size : 10pt; font-weight : bold; } #msg PRE { overflow : auto; white-space : normal; background-color : #ffc; border : 1px #fc0 solid; padding : 6px; } #msg UL, PRE, .diff { overflow : auto; } #patch h4 { font-family : arial,helvetica,sans-serif; font-size : 10pt; } #patch h4 { padding: 8px; background : #369; color : #fff; margin : 0; } #patch .propset h4, #patch .binary h4 {margin: 0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {background:#eeeeee;padding: 0 0 10px 0;} #patch .propset .diff, #patch .binary .diff {padding: 10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch .add {background:#ddffdd;} #patch .rem {background:#ffdddd;} #patch .lines, .info {color:#888888;background:#ffffff;} .diff { width : 100%; } --></style> <title>[rhq-project.org rhq] [2681] [RHQ-1237] the old usage of the ZipInputStream for some reason never works - even if I give a bogus file, it never failed.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>2681</dd> <dt>Author</dt> <dd>mazz</dd> <dt>Date</dt> <dd>2009-01-20 12:41:11 -0600 (Tue, 20 Jan 2009)</dd> </dl> <h3>Log Message</h3> <pre>[RHQ-1237] the old usage of the ZipInputStream for some reason never works - even if I give a bogus file, it never failed. Changing to use the JarFile API which gives me proper exceptions when the zip file isn't fully written. This checkin will also wait up to 30 seconds for the plugin to become valid before aborting. This gives you up to 30 seconds to finish writing the new plugin to the rhq-plugins directory.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#rhqtrunkmodulesenterpriseserverjarsrcmainjavaorgrhqenterpriseservercorepluginProductPluginDeployerjava">rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="rhqtrunkmodulesenterpriseserverjarsrcmainjavaorgrhqenterpriseservercorepluginProductPluginDeployerjava"></a> <div class="modfile"><h4>Modified: rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java (2680 => 2681)</h4> <pre class="diff"> <span class="info">--- rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java 2009-01-20 16:52:01 UTC (rev 2680) +++ rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java 2009-01-20 18:41:11 UTC (rev 2681) </span><span class="lines">@@ -38,9 +38,9 @@ </span><span class="cx"> import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import java.util.jar.Attributes; </span><span class="add">+import java.util.jar.JarEntry; </span><span class="cx"> import java.util.jar.JarFile; import java.util.jar.Manifest; </span><span class="rem">-import java.util.zip.ZipInputStream; </span><span class="cx"> import javax.management.ListenerNotFoundException; import javax.management.MBeanNotificationInfo; </span><span class="lines">@@ -468,24 +468,56 @@ </span><span class="cx"> return pluginDescriptor; } </span><span class="rem">- private void checkDeploymentIsValidZipFile(DeploymentInfo deploymentInfo) throws DeploymentException { - if (deploymentInfo.isDirectory) </span><span class="add">+ private void ensureDeploymentIsValid(DeploymentInfo deploymentInfo) throws DeploymentException { + if (deploymentInfo.isDirectory) { </span><span class="cx"> return; </span><span class="rem">- ZipInputStream zipInputStream = null; </span><span class="add">+ } + + // try 10 times (sleeping 3s between retries) for a total of 30seconds + // if the zip file still isn't valid, its probably corrupted and not simply due to the file still being written out + int retries = 10; + while (!isDeploymentValidZipFile(deploymentInfo)) { + if (--retries <= 0) { + throw new DeploymentException("File [" + deploymentInfo.url + "] is not a valid jarfile - " + + " it is either corrupted or file has not been fully written yet."); + } + try { + Thread.sleep(3000L); + } catch (InterruptedException e) { + break; + } + } + return; + } + + private boolean isDeploymentValidZipFile(DeploymentInfo deploymentInfo) { + boolean isValid; + JarFile jarFile = null; </span><span class="cx"> try { </span><span class="rem">- zipInputStream = new ZipInputStream(deploymentInfo.url.openStream()); - zipInputStream.getNextEntry(); - } catch (IOException e) { - throw new DeploymentException("File [" + deploymentInfo.url + "] is not a valid jarfile - " - + " perhaps the file has not been fully written yet.", e); </span><span class="add">+ // Try to access the plugin jar using the JarFile API. + // Any weird errors usually mean the file is currently being written but isn't finished yet. + // Errors could also mean the file is simply corrupted. + jarFile = new JarFile(new File(deploymentInfo.url.toURI())); + if (jarFile.size() <= 0) { + throw new Exception("There are no entries in the plugin file"); + } + JarEntry entry = jarFile.entries().nextElement(); + entry.getName(); + isValid = true; + } catch (Exception e) { + log.info("File [" + deploymentInfo.url + "] is not a valid jarfile - " + + " the file may not have been fully written yet. Cause: " + e); + isValid = false; </span><span class="cx"> } finally { </span><span class="rem">- if (zipInputStream != null) </span><span class="add">+ if (jarFile != null) { </span><span class="cx"> try { </span><span class="rem">- zipInputStream.close(); - } catch (IOException e) { - log.error("Failed to close zip input stream for file [" + deploymentInfo.url + "]."); </span><span class="add">+ jarFile.close(); + } catch (Exception e) { + log.error("Failed to close jar file [" + deploymentInfo.url + "]"); </span><span class="cx"> } </span><span class="add">+ } </span><span class="cx"> } </span><span class="add">+ return isValid; </span><span class="cx"> } /** </span><span class="lines">@@ -699,7 +731,7 @@ </span><span class="cx"> * of registering the plugins. */ private String preprocessPlugin(DeploymentInfo deploymentInfo) throws DeploymentException { </span><span class="rem">- checkDeploymentIsValidZipFile(deploymentInfo); </span><span class="add">+ ensureDeploymentIsValid(deploymentInfo); </span><span class="cx"> PluginDescriptor descriptor = getPluginDescriptor(deploymentInfo); String pluginName = descriptor.getName(); boolean initialDeploy = !this.deploymentInfos.containsKey(pluginName); </span> </pre> </div> </div> </body> </html> |