2016-11-29 133 views
-1

我正在編寫一個使用翻譯字符串(.properties文件)的應用程序;這些字符串也是由非拉丁字符(實際上,他們是像lenny微笑和像這樣的東西copypastas)。我的問題是,當我在我的IDE Netbeans中點擊「clean and build」然後「run」啓動它時,一切都很順利,所有的字符串都顯示正常......程序按預期行事;但當我將我的項目導出爲胖罐子(我使用的Maven樹蔭插件也包含我的屬性文件),當我啓動它時雙擊它的圖標(仍然在Windows上),一切都搞砸了,因爲有些字符串不顯示:項目在IDE中運行良好,但不能作爲Jar

在我的程序裏面,我使用類LocalisationService(代碼如下)在不同的ArrayList中加載字符串。使用Netbeans運行我的項目,字符串都被正確加載(這是假定的行爲)。在Netbeans之外運行我的jar,只有1/5被正確加載。我的arraylist中有很多「String not found」條目,這意味着,在我的LocalisationService類中,方法getString捕獲MissingResourceException異常。但實際上這些資源不會丟失,我的意思是,我將它們正確地包括在我的罐子裏,Netbeans直接運行我的項目,因爲它應該這樣做,所以...

我完全不知道什麼會導致此問題問題:我的IDE項目編碼設置的UTF-8所以不應該有任何問題...... Maven的運行使用我的項目:

cd C:\Users\utente\Documents\NetBeansProjects\mavenproject1; "JAVA_HOME=C:\\Program Files\\Java\\jdk1.8.0_40" cmd /c "\"\"C:\\Program Files\\NetBeans 8.0.2\\java\\maven\\bin\\mvn.bat\" -Dexec.args=\"-classpath %classpath bot.Main\" -Dexec.executable=\"C:\\Program Files\\Java\\jdk1.8.0_40\\bin\\java.exe\" -Dmaven.ext.class.path=\"C:\\Program Files\\NetBeans 8.0.2\\java\\maven-nblib\\netbeans-eventspy.jar\" -Dfile.encoding=UTF-8 org.codehaus.mojo:exec-maven-plugin:1.2.1:exec\"" 

我在Ubuntu同樣的問題,弦搞砸了我的推出文件從終端與

/usr/bin/java -jar myproject.jar 

這裏是類LocalisationServ冰我用用一鍵獲取正確的本地化字符串:

public class LocalisationService { 
    private static LocalisationService instance = null; 
    private final HashMap<String, String> supportedLanguages = new HashMap<>(); 

    private ResourceBundle english; 
    private ResourceBundle italian; 

private class CustomClassLoader extends ClassLoader { 
    public CustomClassLoader(ClassLoader parent) { 
     super(parent); 

    } 

    public InputStream getResourceAsStream(String name) { 
     InputStream utf8in = getParent().getResourceAsStream(name); 
     if (utf8in != null) { 
      try { 
       byte[] utf8Bytes = new byte[utf8in.available()]; 
       utf8in.read(utf8Bytes, 0, utf8Bytes.length); 
       byte[] iso8859Bytes = new String(utf8Bytes, "UTF-8").getBytes("ISO-8859-1"); 
       return new ByteArrayInputStream(iso8859Bytes); 
      } catch (IOException e) { 
       e.printStackTrace(); 

      } finally { 
       try { 
        utf8in.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     return null; 
    } 
} 

/** 
* Singleton 
* @return Instance of localisation service 
*/ 
public static LocalisationService getInstance() { 
    if (instance == null) { 
     synchronized (LocalisationService.class) { 
      if (instance == null) { 
       instance = new LocalisationService(); 
      } 
     } 
    } 
    return instance; 
} 

/** 
* Private constructor due to singleton 
*/ 
private LocalisationService() { 
    CustomClassLoader loader = new CustomClassLoader(Thread.currentThread().getContextClassLoader()); 
    english = ResourceBundle.getBundle("localisation.strings", new Locale("en", "US"), loader); 
    supportedLanguages.put("en", "English"); 
    italian = ResourceBundle.getBundle("localisation.strings", new Locale("it", "IT"), loader); 
    supportedLanguages.put("it", "Italiano"); 
} 

/** 
* Get a string in default language (en) 
* @param key key of the resource to fetch 
* @return fetched string or error message otherwise 
*/ 
public String getString(String key) { 
    String result; 
    try { 
     result = english.getString(key); 
    } catch (MissingResourceException e) { 
     System.out.println("not found key... "+key); 
     result = "String not found"; 
    } 

    return result; 
} 

/** 
* Get a string in default language 
* @param key key of the resource to fetch from localisations 
* @param language code key for language (such as "EN" for english) 
* @return fetched string or error message otherwise 
*/ 
public String getString(String key, String language) { 
    String result; 
    try { 
     switch (language.toLowerCase()) { 
      case "en": 
       result = english.getString(key); 
       break; 
      case "it": 
       result = italian.getString(key); 
       break; 
      default: 
       result = english.getString(key); 
       break; 
     } 
    } catch (MissingResourceException e) { 
     result = english.getString(key); 
    } 

    return result; 
} 

public HashMap<String, String> getSupportedLanguages() { 
    return supportedLanguages; 
} 

public String getLanguageCodeByName(String language) { 
    return supportedLanguages.entrySet().stream().filter(x -> x.getValue().equals(language)).findFirst().get().getKey(); 
} 
} 

我的項目已經完全沒有錯誤,沒有警告...... 我也嘗試使用運行我的jar文件,在Ubuntu:

/usr/bin/java -Dfile.encoding=UTF-8 -jar myproject.jar 

但仍沒有運氣。

我真的希望你們可以幫助我,我卡在這個問題上,因爲2天都沒有解決辦法...

+4

如果你回過頭來看看你的問題,你可能會發現你沒有給我們提供關於問題如何展現的細節。說「一切都搞砸了」是不夠的。試着從假設我們不知道你曾經嘗試過什麼,並且不知道你做過什麼時發生的事情開始,並且我們不願意在黑暗中猜測什麼可能是錯誤的,當有這麼多你有但沒有提供的信息。 – arcy

+0

「字符串混亂」是什麼意思?當您從Netbeans和命令行運行程序時會發生什麼?有什麼不同?你想要它成爲什麼? –

+0

我不認爲責怪問你問題的人不知道答案是公平的。從代碼中我看起來很清楚問題是什麼,但我也有更多的經驗。 –

回答

1

不要指望InputStream.available()爲您提供準確的信息。

看到一個InputStream轉換爲這裏一個ByteArrayInputStream>Convert InputStream(Image) to ByteArrayInputStream

似乎很清楚,在Netbeans中加載從您的命令行JVM實現上運行時相比,當由父類加載器所提供的InputStream爲有些不同的正確方法。你的代碼並沒有顯示這個代碼被執行的完整上下文,但Netbeans的InputStream實現可能完全填充了available()方法,這給你錯誤的印象是代碼是正確的。

看到https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available()

的InputStream實現文檔不需要填充一個準確值,此方法使你的代碼的結果將通過JVM實現不同而不同。

+0

非常感謝你!這解決了我的問題! – A7X

相關問題