I create jar file which is enbedded and called as applet from ASP.Net web forms application.
I use ResourceBundle to load localized strings from properties.
I created 3 properties files:
localizedStrings.properties
localizedStrings_de.properties
localizedStrings_en.properties
and load strings with
ResourceBundle labels = ResourceBundle.getBundle("localizedStrings", Locale.GERMAN);
However all strings are loaded from strange location : Login.aspx (which is in the same directory with this applet.jar)
When I call Collections.list(labels.getKeys()).get(0)
I see some contents of Login.aspx in there, very unusual, i have tried with some other bundle names and same results.
What could be the problem here?
I would not say it is strange location. Since you haven't provided any location really, the natural place to look for is the Java classpath. If you want to change it somehow, you need to use fully qualified name for base name, i.e.:
ResourceBundle.getBundle("com.my.company.localizedStrings", Locale.GERMAN);
The only doubt I have, since you probably use something like J# is whether that will work. It should.
Related
I want to implement a function that will take package name as input and list all the contents(only files) inside that package.
public List<String> getContents(String packageName) {
...
}
Example input
packageName = com.spring.com.demo
Expexted output
Class1.java
Class2.java
...
What is the best way to accomplish this task?
You're talking about java's 'classloader' system, which is a slight misnomer, in that it can also load resources other than classes. Point is, classes are a resource that are located somewhere, and the JVM itself needs to find them. After all, when you are running your main class and it refers to 'new Foobar()', the jvm needs to find Foobar.class somehow, read the bytes, and turn them into a new class definition.
Java's classloader system is generalized in two ways:
You can call on it to find you stuff.
You can for example write:
MyApp.class.getResource("icons/share.png")
and get a URL object you can pass straight to e.g. ImageIcon. This way, you can ship your icons for your GUI app together with your class files, and it's completely unified: However the system is loading the classes, be it from disk, from inside a jar file, from eclipse's module system if it's an eclipse plugin, or from the network - this way you're loading your images from the same place.
You can make your own
Let's say you want to write a system that loads classes (and other resources, like images) directly from the web. You can do that: You can make your own ClassLoaders.
Now for the crux of the matter
That means ClassLoader is an abstract concept that lists which features it has. It's like any other interface / abstract class in that regard: It's a template that defines what you can do with one, so that anybody can provide you with an implementation of it.
Here's the crucial thing you must understand so that you know why what you want is impossible (and why the commonly called out 'reflections' library is a hack that doesn't universally work):
The ClassLoader abstract simply has no list command.
Hence, listing? Simply not possible. The only command it does have is 'load Resource X', X being some path-like string. That is all it has. The java classloader system is never in need to 'list all classes in a package', not even when there's a star import (which is just a thing javac knows about, at the class file level star imports aren't a thing). The JVM just needs to e.g. load resource '/java/lang/String.class' - hence, the command 'here is a path, please give me the bytes for it' is all that is neccessary.
The solution to have lists anyway
During compilation, the abstractions do support 'list'. After all, the compiler really does just read java files from a directory (which supports 'list all files inside it'), you can't for example tell the compiler 'please compile all .java files in this .jar file). So, at compile time, you can make a list of resources.
So here's the trick: Save that in a text file and ask for the text file during runtime. Then translate each line in the text file to the full resource path and then ask for each of those. Thus, using just the one API call you have available to you at runtime ('load resource at path X'), you can have a list system anyway. It's just that during the compilation/build/packing step you need the tools that compile/build/pack to do some work and make you a text file with the details.
This is called the SPI (Service Provider Interface) system and java itself uses it - it's how JDBC drivers and e.g. charset implementations are found.
You can use this yourself in this three step process:
Define an interface or abstract class that serves as the thing 'providers' will implement/extend. Let's say it is com.ranjan.MyService`.
At the provider end: Write an implementation for it. Let's say it's com.zwitserloot.ServiceImpl.
During compilation, ensure that in the same place the class files end up (e.g. in the jar file for example), there's META-INF/services/com.ranjan.Myservice (a text file). This file contains the fully qualified class name of each 'provider' class: com.zwitserloot.ServiceImpl is what's on the first (and only) line.
At runtime: Use java.util.ServiceLoader and it'll take care of everything.
Your specific use case
From comments it seems like you don't really need to 'list classes', you have a bunch of classes and need to know if they are 'valid', for some definition of 'valid'. You can either just Class.forName them, though this will also initialize them (run its static initializers). Alternatively, you can run YourOwnClass.class.getResource("com.spring.com.demo.Class1.class"), and check that [A] you get an actual resource (and not null, indicating it doesn't exist), and [B] do whatever validation you want to do on this. For example, toss it through bytebuddy or ASM or some other class format editor and check if it can parse it.
I simply want to implement that line programmatically in runtime.
import com.company.package.*;
I can't believe all the searches lead to Python, and I certainly would prefer not loading classes and looping one by one. It must be a faster command.
Any suggestion?
P.S: I know it's not the best of designs, but I am doing it through a JSP, so perhaps there is some way to use a parameter in the declaration as in
<%# page import=%{myPackage} %>
ClassLoader is too dynamic/flexible to do what you're asking. Specifically, there is no portable way to list the contents of a directory from a ClassLoader, so there is no way to determine the complete set of classes to be loaded. Here are two non-portable suggestions:
Assume your ClassLoader implements URLClassLoader, then call getURLs, then assume the URLs are file: ...or:
Assume ClassLoader.getResource("com/company/package/") will return a non-null URL, then assume the URL will be file: (or jar:, then assume the inner URL is file:, and then extract and use that)
In either case, parse file: URL (handling URL decoding), list the contents of the directory/JAR to find all *.class files.
Note, this is basically what Spring classpath*: does, and they include several portability warnings in their documentation for these reasons.
I have a multilingual web application that gets all of the translations from a single object, for example lang.getTranslation("Login") and the object is responsible for finding the translation in an xml file in the user's language.
What I'd like to do is a script / custom static analysis that outputs all the missing translations and translations that are no more used in the application. I believe I should start by programmatically finding every call to the getTranslation method and the string parameter, storing the data in a special structure and comparing it to all the translation files.
Is there a library that will allow me to do this easily? I already found Javassist but I can't use it to read the parameter values. I also tried grepping, but I'm not sure if that's a robust solution (in case there will be a call to another class that has a getTranslation method). I know Qt has a similar mechanism for finding translatable strings in the code, but that's a totally different technology..
I'm asking this because I'm quite sure there's a good existing solution for this and I don't want to reinvent the wheel.
Ok, here's how I did it. Not the optimal solution, but works for me. I created a utility program in Java to find all the method calls and compare the parameters to existing translations.
Find all classes in my project's root package using the Reflections library
Find all getTranslation method calls of the correct class in the classes using the Javassist library and create a list of them (contains: package, class, row number)
Read the appropriate .java files in the project directory from the given row until the ';' character
Extract the parameter value and add it to a list
Find the missing translations and output them
Find the redundant translations and output them
It took me a while to do this, but at least I now have a reusable utility to keep the translation files up to date.
i'm wondering about a specific syntax for the "code" attribute that's used with deployjava.
with something like code: applet.class it's fairly obvious that the call is pointing to a file of that name, presumably in the same directory as the file making the call.
sometimes, though, i see something like code: com.domain.applet.
what is that referring to, and where is that file located in the file structure relative to the script that's making that call?
with something like code: applet.class it's fairly obvious that the call is pointing to a file of that name, presumably in the same directory as the file making the call.
What is obvious is not necessarily the case.
The class might come from a jar, and won't be a loose class file in a directory.
The codebase determines the path to search for classes or jars. It defaults to the current directory when not specified.
Lastly, note that the class attribute should be the 'fully qualified class name'1, and that common nomenclature would have it named as EachWordUpperCase - something like GraphApplet.
sometimes, though, i see something like code: com.domain.applet. what is that referring to, and where is that file located in the file structure relative to the script that's making that call?
OK, let's again assume the applet is called com.domain.GraphApplet - that is the fully qualified name of the GraphApplet class, in package com.domain;.
If that were a loose class file, it would need to be in a directory like ${codebase}/com/domain/. Alternately it would need to be located in the /com/domain/ path inside a jar.
Last note on the FQN. It is common for programmers to add .class e.g. com.domain.GraphApplet.class. While tolerated, that is not correct. It should just be com.domain.GraphApplet
I am currently developing a desktop game as part of my CS course .
Although it is not required I want my application to support Localization
So I browsed the web and found two techniques
- ResourceBundle
- properties file
However I can not decide which is better suited for me , I simply need localized messages and labels for the GUI.
Also I am confused on how such files/classes should be named
for example if FooBar extends ResourceBundle
should be like FooBar_UNIX_en_US
Btw , the assignment is an Entanglement (by gopherwoods studio) clone (Desktop not applet)
~Thanks
You use both - from your program's point of view, they are ResourceBundles, from the translators point of view they are property files. A ResourceBundle can load its strings (only strings, though) from a property file.
So you simply put files like Messages.properties (the default), Messages_eo.properties (the esperanto translation), Messages_de.properties (german translation), Messages_de_AT.properties (special strings for austrian german, overriding the general ones).
In your program you then simply do ResourceBundle bundle = ResourceBundle.getBundle("Messages"), and the runtime builds your resource bundle for the current locale from the property files.
If you need to translate other things than strings, you would need .class files instead, subclassing ResourceBundle. You can even mix both, but I would then better split them to different bundles (i.e. one text bundle and one for the dynamic resources).
You are in the right direction, the convention is typically Name_<language>_<country>.
ResourceBundle itself can use properties file to back the localization string, so you can use that. That way you don't have to compile new classes for each localization you would like to support. Just create a new properties file for the language.
Check out ResourceBundle.getBundle() factory method.
I believe using resource bundles would be the best technique.
Java itself, will attempt to reference your resource bundels by most specific to least specific (most generic).
If you have the following resources:
resource
resource_en
resource_en_GB
resource_fr
resource_fr_CA
And the end users local is en_NZ (New Zeland) he would be shown what is in the resource_en.
However, someone from Quebec, Canada would most likely be shown what is in the resource_fr_CA.
Hope that helps.