2015-12-02 2 views
2

математическая библиотека жеребенка (версия 1.2) зависит от библиотеки EDU.oswego.cs.dl.util.concurrent (gee.cs.oswego.edu/dl/ классы/EDU/Осуиго/CS/дл/Util/параллельный/intro.html). Компиляция concurrent (версия 1.3.4) работала над версией Java версии 7 или предыдущими версиями. Однако компиляция не выполняется на java 8 (версия javac 1.8). Параметры компилятора -source 1.4 -target 1.4 не устраняют проблему.Компиляция провал старой библиотеки в сочетании с тех пор Java 8

Причина в том, что в java 8 был введен новый метод «удалить» в интерфейсе java.util.Map: default boolean remove(Object key, Object value). Этот новый метод сталкивается с методом «удалить» в классе библиотеки ConcurrentHashMap.java, который реализует java.util.Map: protected Object remove(Object key, Object value).

После того, как причина проблемы была идентифицирована, я смог решить проблему , переименовав метод в библиотечный класс ConcurrentHashMap.java. Это было приемлемо, потому что метод библиотеки был защищен только (а не публичный).

Существуют ли другие возможности для обеспечения совместимости с java 8?

  • опции компилятора?
  • аннотации ("@ForceOverride")?
+0

Кажется, другие попали в ту же проблему: [имя Java-столкновение-ошибок, несмотря на-разному-метод-подписи] (http://stackoverflow.com/questions/23785807/java-name-clash-error-despite-different-method-signatures/23785923#23785923). – qwert2003

+0

Я не уверен, что это правильный подход, но мы решили схожие проблемы с этим: http://backport-jsr166.sourceforge.net/ – Marged

+1

Это связано с изменением кода в библиотеке жеребьевки. Вероятно, в долгосрочной перспективе действительно стоит перейти от исходного * concurrent * к java.util.concurrent (я думаю, что в моем случае совместимость для java <6, предоставляемая backport больше не нужна). Я просто боюсь, что это не прямо ... – qwert2003

ответ

2

Нет никаких параметров компилятора или аннотаций, которые будут игнорировать сигнатуры сигнатур конфликта.

Если вы (или, в данном случае, жеребенка) не использовать новый метод remove, просто скомпилировать его под Java 7. Компиляция под Java-не даст вам никаких преимуществ.

Но в этом случае мне действительно нравится ваше решение.

+1

Да, это то, что я сделал сам. Затем мне сообщили (по службе openuse build), что одновременно не компилировались на Fedora 23, возможно, java 7 не был доступен. Но что на самом деле происходит, если кто-то запускает банку (скомпилированную на java 7) на java 8? Я думаю, это может потерпеть неудачу, так как нет java 7 runtime. – qwert2003

+1

Ах. Что ж, похоже, вы сделали лучшее. –

1

Учитывая, что этот класс является основанием класса JRE, также известного как ConcurrentHashMap, здесь нет имени, поскольку этот метод имеет точно намеченную семантику. Столкновение происходит, потому что метод protected, решение, которое уже давно пересмотрено. То есть когда вы смотрите на версию класса Java 5, вы увидите, что она уже имеет the method remove(Object, Object), и это public. Он также требуется ConcurrentMap interface, и поэтому должен бытьpublic.

Таким образом, самым простым решением является не переименование его, а изменение модификатора до public и адаптация возвращаемого типа.


Но вы правы in your comment, в долгосрочной перспективе, лучшим решением будет мигрировать к версии JRE этого класса as recommend by the author himself:

Примечание: При освобождении J2SE 5.0, этот пакет входит режим технического обслуживания: будут выпущены только основные исправления. Пакет J2SE5 java.util.concurrent включает улучшенные, более эффективные, стандартизованные версии основных компонентов этого пакета. Пожалуйста, планируйте конвертировать ваши приложения для их использования.

И это было больше, чем десять лет назад ...

+0

Было рассмотрено изменение модификатора на публичный язык и адаптация типа возвращаемого значения, но оно включает в себя больше изменений, чем просто переименование метода (поскольку используется возвращаемый объект). Но на самом деле это решение довольно похоже на два «переименования» в том смысле, что для этого требуется изменить исходный код библиотеки. Это первый раз, когда я был поражен проблемой несовместимости Java (из-за изменения/улучшения интерфейса карты). Я надеялся, что будет решение, использующее только параметры компилятора. – qwert2003

+0

К сожалению, нет. Для полной совместимости с более ранней версией вам нужно указать опцию '-target' * и * более старую версию библиотеки JRE. Самые последние компиляторы будут предупреждать вас, когда вы укажете опцию '-target' без соответствующей (старой) библиотеки классов ... – Holger

0

Migrate жеребенка от EDU.oswego.cs.dl.util.concurrent до java.util.concurrent классов. Как цитируется в ответе Хольгера, автор библиотеки concurrent рекомендует это сделать.

Gentoo предоставляет patch для жеребенок 1.2.0 исходного кода:

--- src/cern/colt/matrix/linalg/SmpBlas.java.orig 2015-10-07 22:23:44.969486000 +0000 
+++ src/cern/colt/matrix/linalg/SmpBlas.java 2015-10-07 22:29:15.475486000 +0000 
@@ -10,7 +10,8 @@ 

import cern.colt.matrix.DoubleMatrix1D; 
import cern.colt.matrix.DoubleMatrix2D; 
-import EDU.oswego.cs.dl.util.concurrent.FJTask; 
+ 
+import java.util.concurrent.ForkJoinTask; 
/** 
Parallel implementation of the Basic Linear Algebra System for symmetric multi processing boxes. 
Currently only a few algorithms are parallelised; the others are fully functional, but run in sequential mode. 
@@ -198,7 +199,7 @@ 

    // set up concurrent tasks 
    int span = width/noOfTasks; 
- final FJTask[] subTasks = new FJTask[noOfTasks]; 
+ final ForkJoinTask[] subTasks = new ForkJoinTask[noOfTasks]; 
    for (int i=0; i<noOfTasks; i++) { 
     final int offset = i*span; 
     if (i==noOfTasks-1) span = width - span*i; // last span may be a bit larger 
@@ -217,24 +218,30 @@ 
      CC = C.viewPart(offset,0,span,p); 
     } 

-  subTasks[i] = new FJTask() { 
+  subTasks[i] = new ForkJoinTask() { 
      public void run() { 
       seqBlas.dgemm(transposeA,transposeB,alpha,AA,BB,beta,CC); 
       //System.out.println("Hello "+offset); 
      } 
+ 
+  public boolean exec() { return true; } 
+  public void setRawResult(Object o) {} 
+  public Object getRawResult() {return null;} 
     }; 
    } 

    // run tasks and wait for completion 
- try { 
-  this.smp.taskGroup.invoke(
-   new FJTask() { 
-    public void run() { 
-     coInvoke(subTasks); 
-    } 
-   } 
-  ); 
- } catch (InterruptedException exc) {} 
+ this.smp.taskGroup.invoke(
+   new ForkJoinTask() { 
+    public void run() { 
+     invokeAll(subTasks); 
+    } 
+ 
+    public boolean exec() { return true; } 
+    public void setRawResult(Object o) {} 
+    public Object getRawResult() {return null;} 
+   } 
+   ); 
} 
public void dgemv(final boolean transposeA, final double alpha, DoubleMatrix2D A, final DoubleMatrix1D x, final double beta, DoubleMatrix1D y) { 
    /* 
@@ -271,7 +278,7 @@ 

    // set up concurrent tasks 
    int span = width/noOfTasks; 
- final FJTask[] subTasks = new FJTask[noOfTasks]; 
+ final ForkJoinTask[] subTasks = new ForkJoinTask[noOfTasks]; 
    for (int i=0; i<noOfTasks; i++) { 
     final int offset = i*span; 
     if (i==noOfTasks-1) span = width - span*i; // last span may be a bit larger 
@@ -280,24 +287,30 @@ 
     final DoubleMatrix2D AA = A.viewPart(offset,0,span,n); 
     final DoubleMatrix1D yy = y.viewPart(offset,span); 

-  subTasks[i] = new FJTask() { 
+  subTasks[i] = new ForkJoinTask() { 
      public void run() { 
       seqBlas.dgemv(transposeA,alpha,AA,x,beta,yy); 
       //System.out.println("Hello "+offset); 
      } 
+ 
+  public boolean exec() { return true; } 
+  public void setRawResult(Object o) {} 
+  public Object getRawResult() {return null;} 
     }; 
    } 

    // run tasks and wait for completion 
- try { 
-  this.smp.taskGroup.invoke(
-   new FJTask() { 
-    public void run() { 
-     coInvoke(subTasks); 
-    } 
-   } 
-  ); 
- } catch (InterruptedException exc) {} 
+ this.smp.taskGroup.invoke(
+   new ForkJoinTask() { 
+    public void run() { 
+     invokeAll(subTasks); 
+    } 
+ 
+    public boolean exec() { return true; } 
+    public void setRawResult(Object o) {} 
+    public Object getRawResult() {return null;} 
+   } 
+   ); 
} 
public void dger(double alpha, DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix2D A) { 
    seqBlas.dger(alpha,x,y,A); 
@@ -369,9 +382,6 @@ 
/** 
    * Prints various snapshot statistics to System.out; Simply delegates to {@link EDU.oswego.cs.dl.util.concurrent.FJTaskRunnerGroup#stats}. 
    */ 
-public void stats() { 
- if (this.smp!=null) this.smp.stats(); 
-} 
private double xsum(DoubleMatrix2D A) { 
    double[] sums = run(A,true, 
     new Matrix2DMatrix2DFunction() { 
--- src/cern/colt/matrix/linalg/Smp.java.orig 2015-10-07 21:08:19.443486000 +0000 
+++ src/cern/colt/matrix/linalg/Smp.java 2015-10-07 22:28:24.722486000 +0000 
@@ -9,12 +9,13 @@ 
package cern.colt.matrix.linalg; 

import cern.colt.matrix.DoubleMatrix2D; 
-import EDU.oswego.cs.dl.util.concurrent.FJTask; 
-import EDU.oswego.cs.dl.util.concurrent.FJTaskRunnerGroup; 
+import java.util.concurrent.ForkJoinTask; 
+import java.util.concurrent.ForkJoinPool; 
+ 
/* 
*/ 
class Smp { 
- protected FJTaskRunnerGroup taskGroup; // a very efficient and light weight thread pool 
+ protected ForkJoinPool taskGroup; // a very efficient and light weight thread pool 

    protected int maxThreads; 
/** 
@@ -24,41 +25,39 @@ 
    maxThreads = Math.max(1,maxThreads); 
    this.maxThreads = maxThreads; 
    if (maxThreads>1) { 
-  this.taskGroup = new FJTaskRunnerGroup(maxThreads); 
+  this.taskGroup = new ForkJoinPool(maxThreads); 
    } 
    else { // avoid parallel overhead 
     this.taskGroup = null; 
    } 
} 
-/** 
- * Clean up deamon threads, if necessary. 
- */ 
-public void finalize() { 
- if (this.taskGroup!=null) this.taskGroup.interruptAll(); 
-} 
protected void run(final DoubleMatrix2D[] blocksA, final DoubleMatrix2D[] blocksB, final double[] results, final Matrix2DMatrix2DFunction function) { 
- final FJTask[] subTasks = new FJTask[blocksA.length]; 
+ final ForkJoinTask[] subTasks = new ForkJoinTask[blocksA.length]; 
    for (int i=0; i<blocksA.length; i++) { 
     final int k = i; 
-  subTasks[i] = new FJTask() { 
+  subTasks[i] = new ForkJoinTask() { 
      public void run() { 
       double result = function.apply(blocksA[k],blocksB != null ? blocksB[k] : null); 
       if (results!=null) results[k] = result; 
       //System.out.print("."); 
      } 
+  public boolean exec() { return true; } 
+  public void setRawResult(Object o) {} 
+  public Object getRawResult() {return null;} 
     }; 
    } 

    // run tasks and wait for completion 
- try { 
-  this.taskGroup.invoke(
-   new FJTask() { 
-    public void run() { 
-     coInvoke(subTasks); 
-    } 
-   } 
-  ); 
- } catch (InterruptedException exc) {} 
+ this.taskGroup.invoke(
+   new ForkJoinTask() { 
+    public void run() { 
+     invokeAll(subTasks); 
+    } 
+    public boolean exec() { return true; } 
+    public void setRawResult(Object o) {} 
+    public Object getRawResult() {return null;} 
+   } 
+   ); 
} 
protected DoubleMatrix2D[] splitBlockedNN(DoubleMatrix2D A, int threshold, long flops) { 
    /* 
@@ -186,10 +185,4 @@ 
    } 
    return blocks; 
} 
-/** 
- * Prints various snapshot statistics to System.out; Simply delegates to {@link EDU.oswego.cs.dl.util.concurrent.FJTaskRunnerGroup#stats}. 
- */ 
-public void stats() { 
- if (this.taskGroup!=null) this.taskGroup.stats(); 
-} 
} 
Смежные вопросы