Archive comparison

Épp a minap futottam bele egy igen nehéz JBoss és classloader problémába. Persze mi voltunk a hibásak, de azért elvitte az egész napot, amíg megtaláltuk a probléma forrását.

A gond az volt, hogy egy EAR filon belül azegyik WAR tartalmazott egy extra és felesleges log4j jar-t, ami a classloader sajátosságai miatt nem talált configurációt (noha a JBoss jól volt globálisan beállítva) és emiatt az alapértelmezett beállításokat használta, ami minden debug szinten tolt ki. És beleérte valami thirdparty komponest is, ami teljesen kiakasztotta a rendszert. A megoldás az lett, hogy ear shared library szintre hoztuk a log4j jar-t (pontosabban már ott volt, csak a war-ból kellett kegyomlálni). A végén csak egy kis pom file bűvészkedés volt a megoldás.

És hogyan kerüljük el a hasonló problémákat a jövőben? Az a stratégia, hogy a fejlesztés végén a “before” és “after” ear fájlokat üsszehasonlítjuk és a változások alapján rábólintunk, vagy megnézzük még egy alkalommal.

A munka dandárját egy olyan kis utility végzi, ami hierarchikusan kicsomagolja az egymásba ágyazott zip állományokat.

  1import groovy.io.FileType
  2
  3import java.security.MessageDigest
  4
  5File.metaClass.extension {
  6  path.substring(path.lastIndexOf(".") + 1)
  7}
  8File.metaClass.isZip {
  9  ["zip", "ear", "war"].contains(extension())
 10}
 11
 12def LeftFile = /c:\environment\_work\ZipComparison\x\LeftFile.zip/
 13def RightFile = /c:\environment\_work\ZipComparison\x\RightFile.zip/
 14
 15Map leftHashes = generateHash(cleanup(unzip(new File(LeftFile))))
 16Map rightHashes = generateHash(cleanup(unzip(new File(RightFile))))
 17Map diff = mapDiff(leftHashes, rightHashes)
 18printReport(diff)
 19
 20
 21def unzip(File path) {
 22  if (!path.isZip()) {
 23    return path
 24  }
 25  File destination = new File(path.path + ".dir")
 26  if (destination.exists())
 27    destination.deleteDir()
 28  destination.mkdirs()
 29  def ant = new AntBuilder()
 30  ant.project.getBuildListeners().firstElement().setMessageOutputLevel(1)
 31  ant.unzip(src: path.path,
 32      dest: destination.path,
 33      overwrite: "false")
 34
 35  destination.eachFileRecurse(FileType.FILES) { File child ->
 36    unzip(child)
 37  }
 38  return destination
 39}
 40
 41def cleanup(File file) {
 42  file.eachFileRecurse(FileType.FILES) { File f ->
 43    if (f.isZip()) {
 44      f.delete()
 45    }
 46  }
 47  return file;
 48}
 49
 50def generateHash(File dir) {
 51  Map hashes = [:]
 52  dir.eachFileRecurse(FileType.FILES) { File file ->
 53    def md = generateMD5(file)
 54    hashes[file.path.substring(dir.path.length() + 1)] = md
 55  }
 56  hashes
 57}
 58
 59def generateMD5(final File file) {
 60  MessageDigest digest = MessageDigest.getInstance("MD5")
 61  file.withInputStream() { is ->
 62    byte[] buffer = new byte[8192]
 63    int read = 0
 64    while ((read = is.read(buffer)) > 0) {
 65      digest.update(buffer, 0, read);
 66    }
 67  }
 68  byte[] md5sum = digest.digest()
 69  BigInteger bigInt = new BigInteger(1, md5sum)
 70  return bigInt.toString(16).padLeft(32, '0')
 71}
 72
 73
 74def mapDiff(Map oldMap, Map newMap) {
 75  def newKeys = newMap*.key
 76  def oldKeys = oldMap*.key
 77
 78  def removedKeys = oldKeys - newKeys
 79  def addedKeys = newKeys - oldKeys
 80  def commonKeys = newKeys - removedKeys - addedKeys
 81  def changedKeys = commonKeys.findAll { oldMap[it] != newMap[it] }
 82  def unchangedKeys = commonKeys - changedKeys
 83
 84  def changes = [
 85      removed: oldMap.findAll { it.key in removedKeys },
 86      added: newMap.findAll { it.key in addedKeys },
 87      changed: oldMap.findAll { it.key in changedKeys },
 88      unchanged: newMap.findAll { it.key in unchangedKeys }
 89  ]
 90}
 91
 92private void printReport(Map diff) {
 93  println "Only In Left"
 94  println "============"
 95  diff["removed"].each {
 96    println it.key
 97  }
 98  println "Only In Right"
 99  println "============"
100  diff["added"].each {
101    println it.key
102  }
103  println "Changed"
104  println "============"
105  diff["changed"].each {
106    println it.key
107  }
108}
Mar 24, 2014
comments powered by Disqus

Links

Cool

RSS