scala.sys.process简介及实战

原文:http://itang.iteye.com/blog/1126777

简介

Ruby很方便的支持操作系统的调用,如:

 

Ruby代码  收藏代码
  1. irb> system 'dir'  
  2. irb> system 'ls -la'  
  3. irb> system 'curl -I http://www.iteye.com'  
  4. irb> result = `curl -I http://www.iteye.com`  
  5. irb> open("|ls -la"){|it|  it.gets }  
 

 

现在不用羡慕Ruby了,Scala 2.9里也提供类似功能:新增加了package: scala.sys及scala.sys.process, 这些代码最初由SBT(a simple build tool for Scala)项目贡献,主要用于简化与操作系统进程的交互与调用。

 

虽然Java本身通过java.lang.Process提供了这方面的支持,但是API偏底层,易用性不高。

而scala.sys.process提供了漂亮的DSLs,如:

 

Scala代码  收藏代码
  1. //导入定义在process package object里的隐式方法,如!, !!, #> 等  
  2. import scala.sys.process._  
  3. //执行ls -l  
  4. "ls -l" !  
  5. //执行ls -l 并获取标准输出流信息  
  6. val result = "ls -l".!!  
  7. //下载网页  
  8. new java.net.URL("http://www.iteye.com") #> new java.io.File("iteye.html") !  
  

关于scala.sys的更多用法我们可以参考sbt的文档,或阅读scala API

实战

问题描述:

一个maven Web工程使用jetty:run  启动时抛出以下异常:

 

java.util.zip.ZipException: invalid entry size (expected 6659 but got 8867 bytes)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:403)
...
at org.eclipse.jetty.webapp.JarScanner.scan(JarScanner.java:75)
...
 

运行mvn dependency:analyze试图分析工程依赖情况信息时,也抛出同样的异常。

分析异常推测应该是工程依赖的某个jar文件有问题,但是jetty插件抛出异常信息里没有明确的信息指明那些jar有问题。

 

解决思路:

我们可以通过maven命令mvn -X jetty:run 的输出的调试信息找出所有依赖jar的路径。

但是何不给本地maven仓库(位于$HOME/.m2/repository)的所有jar来个大扫荡呢?

说干就干,我们知道jar是以zip文件格式压缩打包的,为了方便起见可利用zip命令行工具来进行校验:

 $ zip -T path

 

 (注:windows系统下可以安装Gow工具包,它里面打包130来个unix 系统的常用工具,如:zip, cat, wget, cURL等等.)

 

实现思路很简单,递归访问$HOME/.m2/repository每个子目录,找出jar文件,并使用系统调用zip工具来验证每个jar文件是否正常。

 

立刻动手:

如果熟悉find命令的话,如下代码即可搞定:

 

Bash代码  收藏代码
  1. $ bash  
  2. bash-2.03$ find . -type f -name \*.jar -exec zip -T {} \;  
 

这次我们用Scala结合系统调用来完成这个任务, Test.scala代码如下:

 

Scala代码  收藏代码
  1. import java.io.File  
  2. import sys.process._  
  3. import actors._  
  4. import Actor._  
  5.   
  6. def isJarFile(file: File) =   
  7.   if(file.isFile && file.getName.endsWith(".jar")) true else false  
  8.   
  9. /**  
  10.  * 遍历找出所有jar并将其传递给处理函数.  
  11.  */  
  12. def walk[T](start: File)(jarFunc: File => T ): Unit = start match {  
  13.   case file if isJarFile(start) =>   
  14.     jarFunc(file)  
  15.   case dir if start.isDirectory =>  
  16.     for(f <- dir.listFiles)  
  17.       walk(f)(jarFunc)  
  18.   case _ =>  
  19. }  
  20.   
  21. //Actor实现的命令执行器  
  22. val processor = actor{  
  23.   loop {  
  24.     react {  
  25.       case cmd:String =>   
  26.         cmd #>> new File("result.txt") ! //#>>执行结果同时写入文件  
  27.     }  
  28.   }  
  29. }  
  30.   
  31. val start = new File(System.getProperty("user.home") + "/.m2/repository")  
  32. walk(start){ jarFile =>  
  33.   //委托给Actor来异步处理  
  34.   processor ! "zip -T " + jarFile.getAbsolutePath  
  35. }  
 

运行,看结果

  $ scala Test.scala

 

打开result.txt一看, 不出意外,一个jar出现问题

 

 

zip error: Zip file structure invalid (C:/Users/itang/.m2/repository/org/springframework/security/spring-security-acl/3.1.0.CI-SNAPSHOT/spring-security-acl-3.1.0.CI-20110715.170427-480.jar)
zip warning: unexpected signature on disk 0 at 74785
 

 

好吧, 我要去处理spring-security-acl的这个jar了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值