Hi,
You guys have created a great product. I have had no
problems using it so far. I just have a bug to report on
removal of unreferenced variables.
Many of us use static declarations like the following in
resource files
protected static final ResourceBundle bundle =
(ResourceBundle) ResourceBundle.getBundle("res.nm");
public static final String var1 = bundle.get(1);
public static final String var2 = "test";
and some times there are 100's of such var declarations
and some of them do not get used in the rest of the
code.
Proguard does not remove var1 (but removes var2)
above for some reason. Is it because it is initialised
statically with a method call on another class ? Note
that var1 is not used anywhere else in the program.
It would be great if proguard can strip this. Sometimes
resource files have 100's of lines of declarations and it is
hard to tell which one's are not used anymore.
Best Regards
Pdham
Logged In: YES
user_id=555208
This may not be what one would want, but it is not a bug.
The field var1 is used, because there is an assignment to it
in the static initializer block. Internally, the compiled
bytecode looks like this:
protected static final ResourceBundle bundle;
public static final String var1;
static
{
bundle = (ResourceBundle)
ResourceBundle.getBundle("res.nm");
var1 = bundle.get(1);
}
The current version of ProGuard recursively marks classes,
methods, and fields that are used in methods that are used,
and it then keeps them. The static initializer is always
kept, and hence the fields 'bundle' and 'var1' are also kept.
Version 3.0 of ProGuard, which I am currently working on,
performs a more in-depth analysis of the individual
instructions. It looks beyond "this instruction accesses
this class/field/method". For instance, it will notice
'var1' is never read (if it isn't read in any other
classes), so it will discard the field.
However, some things will remain difficult to analyze
because of potential side-effects of methods. For instance,
'bundle.get(1)' may or may not have any side-effects.
ProGuard would have to analyze large parts of the run-time
environment (recursively!) to figure out such things. If the
implementation of the method caches some results, that would
be a side-effect. Even the call
'ResourceBundle.getBundle("res.nm")' might throw a
MissingResourceException. In both cases, ProGuard would have
to keep the calls, in order to preserve the identical
behaviour of the original code. A human developer would
immediately say that he doesn't want these exceptions
anyway, but an automatic program generally can't go about
making such changes.
Eric.
Logged In: YES
user_id=666667
I noticed this item has been closed.
Does that mean some work has been done to resolve some
aspects of it (as per your prev comments) or this can't be
done ?
if you find a spare min please comment
cheers
Logged In: YES
user_id=555208
If you now use the option -assumenosideeffects to specify
ResourceBundle.getBundle and ResourceBundle.get, the method
calls may be removed, assuming the fields are never read (in
this case probably just var1). Please let me know if you get
the chance to try it out. I might add it to the boilerplate
configurations in the GUI.