2016-11-29 94 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

相关问题