Vert.x 2.1.3 Classpath question - Locale and .properties.

468 views
Skip to first unread message

bytor99999

unread,
Mar 17, 2015, 12:39:21 AM3/17/15
to ve...@googlegroups.com
So I am getting classpath issues with loading in a .properties file that is being used for our String messages and internationalization. Here is the class and constructor that reads in the .properties file into a ResourceBundle.

@Slf4j
class ResourceBundleMessages {

 
String messages = "i18n/messages"
  ResourceBundle resourceBundle

  public ResourceBundleMessages() {
   
resourceBundle = ResourceBundle.getBundle(messages)
 
}


Pretty simple, straightforward code. It works fine in other applications like a .war file deployed in Jetty. With the .properties file in the exact location as in our Vert.x application inside a jar file that is put in a lib directory of the application.

But the same code running in classes in a Vert.x application fails. The .properties file is in the correct location inside a jar file inside the module we run.

2015-03-16 21:32:16,112 ERROR null-com.hdpoker.gameserver.verticle.GameServerVerticle-1610802782  vert.x-eventloop-thread-3- Exception in Groovy verticle
java.util.MissingResourceException: Can't find bundle for base name i18n/messages, locale en_US
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499) ~[na:1.7.0_71]

Will it only work if the message.properties and other language versions of the .properties file is directly in the VERTX_HOME conf or similar directory?

Thanks

Mark

Jochen Mader

unread,
Mar 17, 2015, 9:16:14 AM3/17/15
to ve...@googlegroups.com
Problem is that properties-Files are loaded through classloaders.
Vert.x 2 (and 3 to soem extend) does things differently than other frameworks.
Classloaders are isolated against each other in a per-verticle-type and additionally on a per-module-basis.
But if they are part of the module you are deploying they should be accessible from all included verticles.
What does your application layout look like?
What's the layout of your project?



--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Jochen Mader | Lead IT Consultant

codecentric AG | Elsenheimerstr. 55a | 80687 München | Deutschland
tel: +49 89 215486633 | fax: +49 89 215486699 | mobil: +49 152 51862390
www.codecentric.de | blog.codecentric.de | www.meettheexperts.de | www.more4fi.de

Sitz der Gesellschaft: Düsseldorf | HRB 63043 | Amtsgericht Düsseldorf
Vorstand: Michael Hochgürtel . Mirko Novakovic . Rainer Vehns
Aufsichtsrat: Patric Fedlmeier (Vorsitzender) . Klaus Jäger . Jürgen Schütz

bytor99999

unread,
Mar 17, 2015, 12:15:05 PM3/17/15
to ve...@googlegroups.com
Yeah. Looks like we have to put them in the VERTX_HOME/conf directory. It seems to only work if that is where we put the /i18n/messages.properties file. One good thing is that it would be outside our application, and we can just add other languages to that directory and automatically use it.

Thanks

Mark

bytor99999

unread,
Mar 17, 2015, 12:18:54 PM3/17/15
to ve...@googlegroups.com
"The .properties file is in the correct location inside a jar file inside the module we run."

So we have one module, inside the modules lib directory is a jar file that includes classes and the .properties file. So, technically with how Vert.x does class loaders, it should find it.

Mark

bytor99999

unread,
Mar 17, 2015, 1:54:06 PM3/17/15
to ve...@googlegroups.com
Tim. I really tried to create a test/sample app that shows this but I failed miserably. It was real simple, had all the code done, but Gradle and Git stood in my way and I spent 2 hours trying to figure out how to get a jar created and put into my local Maven repo so that my module could grab the jar and put it in the module. :D I had the Github repo and everything, but couldn't even push from my machine to that repo. Not like I can with every single other project/repo I created on Github. Sometimes I just think I need to retire and get the hell out of development because I feel like a complete moron when I can't figure out Gradle or Git, especially after using Git for a good 5 years now. You would think I could push to a remote repo.

Mark

bytor99999

unread,
Mar 18, 2015, 2:50:46 PM3/18/15
to ve...@googlegroups.com
So putting it into the conf directory is not a solution.

Here is the class again. Using static methods and static variables.

class ResourceBundleMessages {

 
private static final String BUNDLE_NAME = "i18n/messages"
  private static final ResourceBundle resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME)

 
public static String getString(MessageKey key, Object... params) {
   
try {
     
if (params.size() > 0) {
       
return MessageFormat.format(resourceBundle.getString(key.messageKey), params)
     
} else {
       
return resourceBundle.getString(key.messageKey)
     
}
   
}catch (MissingResourceException e) {
     
log.error("Unable to find Message in message.properties for property of key ${key}", e)
     
return '!' + key + '!';
   
}
 
}
}

The class and the .properties file are in a jar file that is in the lib directory of the Vert.x module.

java.lang.NoClassDefFoundError: Could not initialize class com.hdpoker.gameserver.core.message.domain.systemnotification.ResourceBundleMessages

I am sure it is not finding the .properties file which is in the jar file in the correct location. I know it isn't the classes in the jar as our module uses many of the other classes in the jar file without any issues.

Any ideas why it doesn't see the properties file in the jar file, but did when the same path is in the conf directory of Vert.x 2.1.3 

Thanks

Mark

bytor99999

unread,
Mar 18, 2015, 8:06:54 PM3/18/15
to ve...@googlegroups.com
This is how we got it to work. We found a class that is in the jar file too and load up the bundle via passing in a different classloader.

ClassLoader loader = Message.class.getClassLoader()
resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), loader)

Problem is now it isn't internationalization code, it will only be one Locale. The server's local.

Mark
Reply all
Reply to author
Forward
0 new messages