Code Monkey home page Code Monkey logo

jardiff's Introduction

JAR differ

A tool for generating bytecode diffs

Requires JDK 8+

About

JarDiff is a tool for generating detailed but comprehensible diffs of sets (JAR or directory) of Java classfiles.

Class files are rendered with ASM's Textifier and with scalap. Other files are rendered as-is.

The rendered files are committed into a Git repository, one commit per provided command line argument.

The diffs between these are rendered to standard out (unless --quiet is provided). If only a single argument is provided, the initial commit is rendered.

By default, a temporary git repository is used and deleted on exit. Use --git to provide a custom location for the repository that can be inspected after the tool has run.

Installing

macOS

macOS users may install with:

brew install retronym/formulas/jardiff

Other Platforms

Usage

% jardiff -h
usage: jardiff [-c] [-g <dir>] [-h] [-i <arg>] [-p] [-q] [-r] [-U <n>] VERSION1 [VERSION2 ...]

Each VERSION may designate a single file, a directory, JAR file or a
`:`-delimited classpath

 -c,--suppress-code       Suppress method bodies
 -g,--git <dir>           Directory to output a git repository containing the
                          diff
 -h,--help                Display this message
 -i,--ignore <arg>        File pattern to ignore rendered files in gitignore
                          format
 -p,--suppress-privates   Display only non-private members
 -q,--quiet               Don't output diffs to standard out
 -r,--raw                 Disable sorting and filtering of classfile contents
 -U,--unified <n>         Number of context lines in diff

% jardiff dir1 dir2

% jardiff v1/A.class v2/A.class

% jardiff --git /tmp/diff-repo --quiet v1.jar v2.jar v3.jar

Building

After cloning this project, use sbt clean core/assembly.

Sample Output

Scala 2.11 vs 2.12 trait encoding changes

// test.scala
trait T { def foo = 4 }
class C extends T
% ~/scala/2.11/bin/scalac -d /tmp/v1 test.scala && ~/scala/2.12/bin/scalac -d /tmp/v2 test.scala

% jardiff /tmp/v1 /tmp/v2
diff --git a/C.class.asm b/C.class.asm
index f3a33f1..33b9282 100644
--- a/C.class.asm
+++ b/C.class.asm
@@ -1,4 +1,4 @@
-// class version 50.0 (50)
+// class version 52.0 (52)
 // access flags 0x21
 public class C implements T  {
 
@@ -8,7 +8,7 @@
     ALOAD 0
     INVOKESPECIAL java/lang/Object.<init> ()V
     ALOAD 0
-    INVOKESTATIC T$class.$init$ (LT;)V
+    INVOKESTATIC T.$init$ (LT;)V
     RETURN
     MAXSTACK = 1
     MAXLOCALS = 1
@@ -16,7 +16,7 @@
   // access flags 0x1
   public foo()I
     ALOAD 0
-    INVOKESTATIC T$class.foo (LT;)I
+    INVOKESTATIC T.foo$ (LT;)I
     IRETURN
     MAXSTACK = 1
     MAXLOCALS = 1
diff --git a/T.class.asm b/T.class.asm
index 9180093..fcac19f 100644
--- a/T.class.asm
+++ b/T.class.asm
@@ -1,8 +1,28 @@
-// class version 50.0 (50)
+// class version 52.0 (52)
 // access flags 0x601
 public abstract interface T {
 
 
-  // access flags 0x401
-  public abstract foo()I
+  // access flags 0x9
+  public static $init$(LT;)V
+    // parameter final synthetic  $this
+    RETURN
+    MAXSTACK = 0
+    MAXLOCALS = 1
+
+  // access flags 0x1
+  public default foo()I
+    ICONST_4
+    IRETURN
+    MAXSTACK = 1
+    MAXLOCALS = 1
+
+  // access flags 0x1009
+  public static synthetic foo$(LT;)I
+    // parameter final synthetic  $this
+    ALOAD 0
+    INVOKESPECIAL T.foo ()I
+    IRETURN
+    MAXSTACK = 1
+    MAXLOCALS = 1
 }

Scala standard library changes during 2.11 minor releases

% jardiff --quiet --git /tmp/scala-library-diff /Users/jz/scala/2.11.*/lib/scala-library.jar

Browsable Repo: scala-library-diff

API changes visible in bytecode descriptors / generic signature / scalap output

// V1.scala
trait C {
  def m1(a: String)
  def m2(a: Option[String])
  def m3(a: String)
}
// V2.scala
trait C {
  def m1(a: AnyRef)
  def m2(a: Option[AnyRef])
  def m3(a: scala.collection.immutable.StringOps) // value class
}
diff --git a/C.class.asm b/C.class.asm
index 52a43d5..bdb0541 100644
--- a/C.class.asm
+++ b/C.class.asm
@@ -4,12 +4,12 @@
 
 
   // access flags 0x401
-  public abstract m1(Ljava/lang/String;)V
+  public abstract m1(Ljava/lang/Object;)V
     // parameter final  a
 
   // access flags 0x401
-  // signature (Lscala/Option<Ljava/lang/String;>;)V
-  // declaration: void m2(scala.Option<java.lang.String>)
+  // signature (Lscala/Option<Ljava/lang/Object;>;)V
+  // declaration: void m2(scala.Option<java.lang.Object>)
   public abstract m2(Lscala/Option;)V
     // parameter final  a
 
diff --git a/C.class.scalap b/C.class.scalap
index 78f7d91..637cd98 100644
--- a/C.class.scalap
+++ b/C.class.scalap
@@ -1,5 +1,5 @@
 trait C extends scala.AnyRef {
-  def m1(a: scala.Predef.String): scala.Unit
-  def m2(a: scala.Option[scala.Predef.String]): scala.Unit
-  def m3(a: scala.Predef.String): scala.Unit
+  def m1(a: scala.AnyRef): scala.Unit
+  def m2(a: scala.Option[scala.AnyRef]): scala.Unit
+  def m3(a: scala.collection.immutable.StringOps): scala.Unit
 }

Validating a Scala compiler nightly

% git clone --quiet --depth 1 akka/akka; cd akka

% cat ~/.sbt/0.13/resolver.sbt 
resolvers ++= (
  if (scalaVersion.value.contains("-bin"))
     List("scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/")
  else Nil
)

% for v in 2.12.2 2.12.3-bin-bd6294d; do \
  echo $v; \
  mkdir -p /tmp/akka-$v; \
  time sbt ++$v clean package &>/dev/null; \
  for f in $(find . -name '*.jar'); do cp $f /tmp/akka-$v/; done; \
done

2.12.2

real	3m19.468s
user	8m56.947s
sys	0m17.343s
2.12.3-bin-bd6294d

real	2m57.631s
user	8m40.168s
sys	0m16.172s

% jardiff -q --git /tmp/akka-diff $(find /tmp/akka-2.12.2 | paste -s -d : -) $(find /tmp/akka-2.12.3-bin-bd6294d | paste -s -d : -)

The resulting diff shows that the only change in the generated bytecode is due to scala/scala#5857, "Fix lambda deserialization in classes with 252+ lambdas"

% git --git-dir /tmp/akka-diff/.git log -p -1
commit 83f0e0a5dabbdf1b7677363bf238d81e4c5b032e (HEAD -> master)
Author: Jason Zaugg <[email protected]>
Date:   Mon Jun 5 17:08:17 2017 +1000

    jardiff textified output of: /tmp/akka-2.12.3-bin-bd6294d:/tmp/akka-2.12.3-bin-bd6294d/akka-2.5-SNAPSHOT.jar:...

diff --git a/akka/stream/scaladsl/GraphApply.class.asm b/akka/stream/scaladsl/GraphApply.class.asm
index 5672560..4d1fafb 100644
--- a/akka/stream/scaladsl/GraphApply.class.asm
+++ b/akka/stream/scaladsl/GraphApply.class.asm
@@ -2802,6 +2802,8 @@ public abstract interface akka/stream/scaladsl/GraphApply {
 
   // access flags 0x100A
   private static synthetic $deserializeLambda$(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
+    TRYCATCHBLOCK L0 L1 L1 java/lang/IllegalArgumentException
+   L0
     ALOAD 0
     INVOKEDYNAMIC lambdaDeserialize(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object; [
       // handle kind 0x6 : INVOKESTATIC
@@ -3308,12 +3310,20 @@ public abstract interface akka/stream/scaladsl/GraphApply {
       // handle kind 0x6 : INVOKESTATIC
       akka/stream/scaladsl/GraphApply.$anonfun$create$250(Lscala/Function1;Ljava/lang/Object;)Ljava/lang/Object;, 
       // handle kind 0x6 : INVOKESTATIC
-      akka/stream/scaladsl/GraphApply.$anonfun$create$251(Lscala/Function1;Ljava/lang/Object;)Ljava/lang/Object;, 
+      akka/stream/scaladsl/GraphApply.$anonfun$create$251(Lscala/Function1;Ljava/lang/Object;)Ljava/lang/Object;
+    ]
+    ARETURN
+   L1
+    ALOAD 0
+    INVOKEDYNAMIC lambdaDeserialize(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object; [
+      // handle kind 0x6 : INVOKESTATIC
+      scala/runtime/LambdaDeserialize.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
+      // arguments:
       // handle kind 0x6 : INVOKESTATIC
       akka/stream/scaladsl/GraphApply.$anonfun$create$252(Lscala/Function1;Ljava/lang/Object;)Ljava/lang/Object;
     ]
     ARETURN
-    MAXSTACK = 1
+    MAXSTACK = 2
     MAXLOCALS = 1
 
   // access flags 0x9

jardiff's People

Contributors

ashawley avatar dwijnand avatar lrytz avatar mdedetrich avatar olafurpg avatar philippus avatar retronym avatar scala-steward avatar sethtisue avatar sideeffffect avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jardiff's Issues

Split core into core and cli sbt subprojects

Currently sbt assembly has a single core project that implements everything however it makes sense to separate the core into core and cli (i.e. the cli runner that uses "commons-cli") with the intent that only core gets published to maven and cli is what the assembly jar is made out of.

Add Windows support

scala.tools.jardiff.IOUtilSpec is failing on Windows and it appears that scala.tools.jardiff.IOUtil.rootPath needs to be changed so its Windows aware, see #152 (comment)

Add option to use javap instead of asm

ASM desugars certain details when disassembling classfiles, for example it eliminates redundant line numbers:

$ javap -v -cp a C
...
  public void t();
...
      LineNumberTable:
        line 2: 0
        line 3: 0
        line 4: 3

whereas

$ asm a/C.class
$ cat a/C.asm
...
  public t()V
   L0
    LINENUMBER 3 L0
    LDC ""
   L1
    ASTORE 1
   L2
    LINENUMBER 4 L2

java.nio.file.FileSystemException: Incorrect function

I'm trying to compare changes in some proprietary software, so I can't share the source here, but I'm getting an exception like

java.nio.file.FileSystemException: [...] AppData\Local\Temp\jardiff-7176758906788730580\cON.class.asm: Incorrect function
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:236)
        at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:478)
        at java.base/java.nio.file.Files.newOutputStream(Files.java:224)
        at java.base/java.nio.file.Files.newBufferedWriter(Files.java:2997)
        at java.base/java.nio.file.Files.newBufferedWriter(Files.java:3040)
        at scala.tools.jardiff.AsmTextifyRenderer.render(AsmTextifyRenderer.scala:29)
        at scala.tools.jardiff.JarDiff.$anonfun$renderFile$1(JarDiff.scala:107)
        at scala.tools.jardiff.JarDiff.$anonfun$renderFile$1$adapted(JarDiff.scala:105)
        at scala.collection.immutable.List.foreach(List.scala:312)
        at scala.tools.jardiff.JarDiff.renderFile(JarDiff.scala:105)
        at scala.tools.jardiff.JarDiff.$anonfun$renderFiles$1(JarDiff.scala:98)
        at scala.tools.jardiff.JarDiff.$anonfun$renderFiles$1$adapted(JarDiff.scala:98)
        at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:47)
        at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:37)
        at java.base/java.nio.file.Files.walkFileTree(Files.java:2804)
        at scala.tools.jardiff.IOUtil$.mapRecursive(IOUtil.scala:37)
        at scala.tools.jardiff.JarDiff.renderFiles(JarDiff.scala:98)
        at scala.tools.jardiff.JarDiff.$anonfun$diff$1(JarDiff.scala:37)
        at scala.collection.immutable.List.foreach(List.scala:312)
        at scala.tools.jardiff.JarDiff.renderAndCommit$1(JarDiff.scala:34)
        at scala.tools.jardiff.JarDiff.$anonfun$diff$3(JarDiff.scala:54)
        at scala.collection.Iterator$$anon$9.next(Iterator.scala:554)
        at scala.collection.Iterator$GroupedIterator.takeDestructively(Iterator.scala:205)
        at scala.collection.Iterator$GroupedIterator.go(Iterator.scala:220)
        at scala.collection.Iterator$GroupedIterator.fill(Iterator.scala:257)
        at scala.collection.Iterator$GroupedIterator.hasNext(Iterator.scala:261)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1196)
        at scala.tools.jardiff.JarDiff.diff(JarDiff.scala:55)
        at scala.tools.jardiff.Main$.run(Main.scala:84)
        at scala.tools.jardiff.Main$.main(Main.scala:20)
        at scala.tools.jardiff.Main.main(Main.scala)

Using java 16. Any ideas what may be causing that?

Error: Illegal character in opaque part at index 47

java -jar jardiff.jar file1.jar file2.jar
java.lang.IllegalArgumentException: Illegal character in opaque part at index 47: jar:file:file1.jar
        at java.net.URI.create(Unknown Source)
        at scala.tools.jardiff.IOUtil$.rootPath(IOUtil.scala:16)
        at scala.tools.jardiff.JarDiff.$anonfun$diff$1(JarDiff.scala:35)
        at scala.collection.immutable.List.foreach(List.scala:312)
        at scala.tools.jardiff.JarDiff.renderAndCommit$1(JarDiff.scala:34)
        at scala.tools.jardiff.JarDiff.$anonfun$diff$3(JarDiff.scala:54)
        at scala.collection.Iterator$$anon$9.next(Iterator.scala:554)
        at scala.collection.Iterator$GroupedIterator.takeDestructively(Iterator.scala:205)
        at scala.collection.Iterator$GroupedIterator.go(Iterator.scala:220)
        at scala.collection.Iterator$GroupedIterator.fill(Iterator.scala:257)
        at scala.collection.Iterator$GroupedIterator.hasNext(Iterator.scala:261)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1196)
        at scala.tools.jardiff.JarDiff.diff(JarDiff.scala:55)
        at scala.tools.jardiff.Main$.run(Main.scala:84)
        at scala.tools.jardiff.Main$.main(Main.scala:20)
        at scala.tools.jardiff.Main.main(Main.scala)
Caused by: java.net.URISyntaxException: Illegal character in opaque part at index 47: jar:file:file1.jar
        at java.net.URI$Parser.fail(Unknown Source)
        at java.net.URI$Parser.checkChars(Unknown Source)
        at java.net.URI$Parser.parse(Unknown Source)
        at java.net.URI.<init>(Unknown Source)
        ... 18 more

Roll a release

to ship #103 in particular

(but perhaps there's other changes we should get out there, too)

jardiff writes to inaccessible directories by default

Jardiff writes to inaccessible temp directories on cygwin/windows 10. Perhaps my system is to blame, but i thought i'd at least let you know.

jardiff original_jars/com.adobe.granite.auth.saml-0.3.22-CQ600-B0002.jar SamlAuthenticationHandler.class.disassembled/modified_jar/com.adobe.granite.auth.saml-0.3.22-CQ600-B0002.jar 
java.nio.file.AccessDeniedException: C:\Users\TIM~1.ZWA\AppData\Local\Temp\jardiff-5317224012050958007\.git\objects\02\53b037b639f215149712695d3412a2f6744766
        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
        at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
        at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
        at java.nio.file.Files.delete(Files.java:1126)
        at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:66)
        at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:64)
        at java.nio.file.Files.walkFileTree(Files.java:2670)
        at java.nio.file.Files.walkFileTree(Files.java:2742)
        at scala.tools.jardiff.IOUtil$.deleteRecursive(IOUtil.scala:64)
        at scala.tools.jardiff.JarDiff.diff(JarDiff.scala:54)
        at scala.tools.jardiff.Main$.run(Main.scala:79)
        at scala.tools.jardiff.Main$.main(Main.scala:20)
        at scala.tools.jardiff.Main.main(Main.scala)

Error when trying to compare Scala jars

I've got this exception when tried to compare Jar files for Scala project:

scala.MatchError: ExistentialType(TypeRefType(ThisType(akka.dispatch),akka.dispatch.RequiresMessageQueue,List(TypeRefType(NoPrefixType,TypeSymbol(_$4, owner=24, flags=100, info=162 ),List()))),List(TypeSymbol(_$4, owner=24, flags=100, info=162 ))) (of class scala.tools.scalap.scalax.rules.scalasig.ExistentialType)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.toString(ScalaSigPrinter.scala:331)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.toString(ScalaSigPrinter.scala:324)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printType(ScalaSigPrinter.scala:320)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printMethodType(ScalaSigPrinter.scala:219)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printMethod(ScalaSigPrinter.scala:258)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printSymbol(ScalaSigPrinter.scala:63)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.$anonfun$printChildren$1(ScalaSigPrinter.scala:90)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.$anonfun$printChildren$1$adapted(ScalaSigPrinter.scala:90)
	at scala.collection.immutable.List.foreach(List.scala:312)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printChildren(ScalaSigPrinter.scala:90)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printClass(ScalaSigPrinter.scala:146)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printSymbol(ScalaSigPrinter.scala:61)
	at scala.tools.scalap.scalax.rules.scalasig.ScalaSigPrinter.printSymbol(ScalaSigPrinter.scala:30)
	at scala.tools.scalap.Main.parseScalaSignature(Main.scala:89)
	at scala.tools.scalap.Main.decompileScala(Main.scala:98)
	at scala.tools.jardiff.ScalapRenderer.render(ScalapRenderer.scala:18)
	at scala.tools.jardiff.JarDiff.$anonfun$renderFile$1(JarDiff.scala:107)
	at scala.tools.jardiff.JarDiff.$anonfun$renderFile$1$adapted(JarDiff.scala:105)
	at scala.collection.immutable.List.foreach(List.scala:312)
	at scala.tools.jardiff.JarDiff.renderFile(JarDiff.scala:105)
	at scala.tools.jardiff.JarDiff.$anonfun$renderFiles$1(JarDiff.scala:98)
	at scala.tools.jardiff.JarDiff.$anonfun$renderFiles$1$adapted(JarDiff.scala:98)
	at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:47)
	at scala.tools.jardiff.IOUtil$$anon$1.visitFile(IOUtil.scala:37)
	at java.nio.file.Files.walkFileTree(Files.java:2670)
	at scala.tools.jardiff.IOUtil$.mapRecursive(IOUtil.scala:37)
	at scala.tools.jardiff.JarDiff.renderFiles(JarDiff.scala:98)
	at scala.tools.jardiff.JarDiff.$anonfun$diff$1(JarDiff.scala:37)
	at scala.collection.immutable.List.foreach(List.scala:312)
	at scala.tools.jardiff.JarDiff.renderAndCommit$1(JarDiff.scala:34)
	at scala.tools.jardiff.JarDiff.$anonfun$diff$3(JarDiff.scala:54)
	at scala.collection.Iterator$$anon$9.next(Iterator.scala:554)
	at scala.collection.Iterator$GroupedIterator.takeDestructively(Iterator.scala:205)
	at scala.collection.Iterator$GroupedIterator.go(Iterator.scala:220)
	at scala.collection.Iterator$GroupedIterator.fill(Iterator.scala:257)
	at scala.collection.Iterator$GroupedIterator.hasNext(Iterator.scala:261)
	at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
	at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1196)
	at scala.tools.jardiff.JarDiff.diff(JarDiff.scala:55)
	at scala.tools.jardiff.Main$.run(Main.scala:84)
	at scala.tools.jardiff.Main$.main(Main.scala:20)
	at scala.tools.jardiff.Main.main(Main.scala)

Diff not showing removed classes

I presume it's something to do with this line:

git.rm().setCached(true).addFilepattern(".")

Doesn't it need a call()?

I assume it's trying to remove everything? I don't believe rm is recursive, though.

Add support for WAR archives

Running the command jardiff --git ~/git/myProject/ test.war prod.war, generates the following output:

diff --git a/prod.war b/prod.war
new file mode 100644
index 0000000..cdee43a
--- /dev/null
+++ b/prod.war
Binary files differ
diff --git a/test.war b/test.war
deleted file mode 100644
index 808fcae..0000000
--- a/test.war
+++ /dev/null
Binary files differ

It seems that jardiff sees war archives as binary files. The workaround is to change the extension of the file to .jar. In that case it works fine.

SBT Plugin

Add a convenient way for SBT users to compare the current results of package to a specified reference version, in the same way as MiMa.

Homebrew formula is warning about Java dependency

Warning: Calling depends_on :java is deprecated! Use "depends_on "openjdk@11", "depends_on "openjdk@8" or "depends_on "openjdk" instead.
Please report this issue to the retronym/formulas tap (not Homebrew/brew or Homebrew/core), or even better, submit a PR to fix it:
  /usr/local/Homebrew/Library/Taps/retronym/homebrew-formulas/jardiff.rb:9

Binary distribution

Don't ask users to clone and build to run the tool.

Publish binaries, and perhaps offer a homebrew recipe.

Scala Native support

I think this would greatly benefit from being cross-built with Scala Native.

However that has impact on its use of Java library such as JGit.

Publish jardiff to maven

Would it be possible to publish this repo as a standard Maven JAR into maven central? The main reasoning behind this is to allow for alternate ways to launch jardiff, specifically coursier which for example would allow you to run jardiff which this simple command

cs launch org.scala-lang::jardiff:1.7.0 args

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.