2017-03-22 9 views
0

コードは以下のとおりです。だから私午前Java 8のlambdaは余分な括弧が嫌いですか?

Type 'java/lang/Object' (current frame, locals[4]) is not assignable to 'com/x/game/model/GameSession' (stack map, locals[4]) 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 
2017-03-22 20:04:34.269 ERROR 26812 --- [   main] o.s.boot.SpringApplication    : Application startup failed 

java.lang.VerifyError: Inconsistent stackmap frames at branch target 49 
Exception Details: 
    Location: 
    com/x/game/repository/FileSystemGameSessionRepositoryImpl.lambda$getAllGameSessions$1(Ljava/nio/file/Path;)Lcom/x/game/model/GameSession; @49: aload 
    Reason: 
    Type 'java/lang/Object' (current frame, locals[4]) is not assignable to 'com/x/game/model/GameSession' (stack map, locals[4]) 
    Current Frame: 
    bci: @20 
    flags: { } 
    locals: { 'com/x/game/repository/FileSystemGameSessionRepositoryImpl', 'java/nio/file/Path', 'java/io/BufferedReader', null, 'java/lang/Object' } 
    stack: { 'java/io/BufferedReader' } 
    Stackmap Frame: 
    bci: @49 
    flags: { } 
    locals: { 'com/x/game/repository/FileSystemGameSessionRepositoryImpl', 'java/nio/file/Path', 'java/io/BufferedReader', 'java/lang/Throwable', 'com/x/game/model/GameSession' } 
    stack: { } 
    Bytecode: 
    0x0000000: 2bb8 0006 4d01 4e2a b400 042c 1207 b600 
    0x0000010: 083a 042c c600 1d2d c600 152c b600 0aa7 
    0x0000020: 0012 3a05 2d19 05b6 000c a700 072c b600 
    0x0000030: 0a19 04b0 3a04 1904 4e19 04bf 3a06 2cc6 
    0x0000040: 001d 2dc6 0015 2cb6 000a a700 123a 072d 
    0x0000050: 1907 b600 0ca7 0007 2cb6 000a 1906 bf4d 
    0x0000060: 2cb6 000e 01b0       
    Exception Handler Table: 
    bci [27, 31] => handler: 34 
    bci [7, 19] => handler: 52 
    bci [7, 19] => handler: 60 
    bci [70, 74] => handler: 77 
    bci [52, 62] => handler: 60 
    bci [0, 49] => handler: 95 
    bci [52, 95] => handler: 95 
    Stackmap Table: 
    full_frame(@34,{Object[#72],Object[#105],Object[#74],Object[#75],Object[#91]},{Object[#75]}) 
    same_frame(@45) 
    same_frame(@49) 
    full_frame(@52,{Object[#72],Object[#105],Object[#74],Object[#75]},{Object[#75]}) 
    same_locals_1_stack_item_frame(@60,Object[#75]) 
    full_frame(@77,{Object[#72],Object[#105],Object[#74],Object[#75],Top,Top,Object[#75]},{Object[#75]}) 
    same_frame(@88) 
    same_frame(@92) 
    full_frame(@95,{Object[#72],Object[#105]},{Object[#77]}) 

    at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_121] 
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_121] 
    at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_121] 
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613) ~[spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE] 

は明らかに問題のテキストである:私はアプリを起動すると

private ObjectMapper mapper = new ObjectMapper(); 
@Override 
     public List<GameSession> getAllGameSessions() { 
      try { 
       return Files.list(Paths.get(BASE_DIR)).filter(path -> path.getFileName().toString().endsWith(FILE_FORMAT_JSON)) 
         .map(path -> { 
          try (BufferedReader bufferedReader = Files.newBufferedReader(path)) { 
           return (mapper.readValue(bufferedReader, GameSession.class)); 
          } catch (IOException ioException) { 
           ioException.printStackTrace(); 
           return null; 
          } 
         }).filter(gameSession -> gameSession!=null).collect(Collectors.toList()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return Collections.emptyList(); 
      } 
     } 

は(春ブーツは)私はとして読み込み、やや不可解なスタイルの例外を取得しますあまりにも巧妙なやり方をしたり、Java 8にはまだ私が発見していないラムダ制限がいくつかあります。

IntelliJは幸いですが、ランタイムはありません。ラムダマップブロック全体をnew GameSession();で置き換えた場合、幸いな日です。問題を発見

答えて

3

これはhorrible way, javac compiles try(…) constructsに関連していますが、これは単なる推測です。少なくとも、私は、この動作が任意のサードパーティ製のコードやバイトコード変換ツールを使用しない、次のMCVEと再現性があることを確認することができますIdeone

import java.util.function.Supplier; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 

public class Tmp { 
    static <T> T readValue(Supplier<T> s, Class<T> type) throws Exception { 
     return s.get(); 
    } 
    interface Source extends Supplier<String>, AutoCloseable { 
     public default void close() throws Exception {} 
    } 

    public static void main(String[] args) { 
     Stream.of("one", "two", "three") 
       .map(s -> { 
        try(Source source =() -> s) { 
         return (readValue(source, String.class)); 
        } 
        catch(Exception ex) { 
         return null; 
        } 
       }) 
       .forEach(System.out::println); 
    } 
} 

テスト可能にし、中括弧を除去することはありませんindeed change the result


私が見る限り、これはJava 8およびそれ以前のバージョンのJava 9(b66以降で動作)のすべてのバージョンに影響します。

+1

私を驚かせることは決してありません!あなたがリンクした答えは絶対に素晴らしいです。 – Eugene

0

は... return (mapper.readValue(bufferedReader, GameSession.class));

エクストラ括弧のタイプミス、私はいつも、余分な括弧は、任意の違いを確認しないと思いました。まあ、楽しい探しの例外は、それがする証拠です。説明したい人は誰でも、この行動を説明する答えを受け入れます。

他の人が解決策を見つけることができるように更新されました。

0

これはおそらく何もこれらの括弧にに関連しているが、代わりに、あなたは(も、それを知らなくてもよい)を使用しているいくつかのバイトコード操作ツール。それはJRebelやSpring BootのSpring Loaderなどかもしれません。

これらのカッコを入れると、古い戦争を取り除いたり、何かを掃除したりするなど、何かもっとやったことがあります。

+3

中かどうかは、バイトコードを処理するツール/ライブラリを使わずに、違いを作ります。 – Holger

関連する問題