I use log4j for logging and tend to include the following snipet in
all my classes...
public class MyClass {
// Logging Declarations
private static String _className;
private static Category _cat;
static {
_className = MyClass.class.getName();
_cat = Category.getInstance(_className);
}
............
}
this works fine until you start to investigate obfuscation and in
particular RetroGuard; Retroguard correctly changes MyClass to be
some funny name but when the code executes the static initialiser
fails with ClassNotFoundException since MyClass.class.getName is not
myFunnyName.class.getName
What I really want is a way in a static intialiser to get .class but I
don't have a this so can't do a this.class. Any ideas?
I have a horrible hack... create a funny Constructor and create an
instance using the funny Constructor;then discard the instance.
e.g.
public class MyClass {
// Logging Declarations
private static String _className;
private static Category _cat;
static {
_className = new MyClass(_cat).class.getName();
_cat = Category.getInstance(_className);
}
private MyClass(Category c) {}
............
}
but I don't like it...
So the big question is... How do I get .class in a static context?
Thanks,
Gavin
Silvio Bierman - 10 Oct 2003 15:16 GMT
This is a common problem with obfuscators that change class names. Javac
changes ClassName.class with Class.forname("ClassName") during compilation.
Retroguard will change the name of ClassName to something cryptic, but it
will not modify the string that is passed to class.forName() resulting in
that call failing.
I have suggested the makers to do also modify the String and they agreed
that would be better, but there has not been a new release since.
If it is not to inefficient you could replace 'ClassName.class' with 'new
ClassName().getClass()' to be obfuscator-insensitive. This is not an option
in your static initializer I am affraid.
Regards,
Silvio Bierman
PerfectDayToChaseTornados - 10 Oct 2003 18:55 GMT
| I use log4j for logging and tend to include the following snipet in
| all my classes...
[quoted text clipped - 51 lines]
| Thanks,
| Gavin
You could use Logger.getRootLogger() if you do not need to log to specific
files for particular classes.

Signature
-P
"Sometimes I feel so goddam' trapped by everything that I know"
Raymond DeCampo - 10 Oct 2003 21:10 GMT
> I use log4j for logging and tend to include the following snipet in
> all my classes...
[quoted text clipped - 51 lines]
> Thanks,
> Gavin
Well, not to answer your question but maybe to solve your problem, why
don't you just put the classname in yourself? It's a little more
maintainence and error-prone, but it would work:
public class MyClass
{
private static final Logger log =
Logger.getLogger("com.myCompany.MyClass");
}
There's nothing magic in log4j about using the class reference to pass
the name, it just wants a string.
Ray
Gavin Andrews - 13 Oct 2003 12:04 GMT
Thanks for the feedback.
>> Javac changes ClassName.class with Class.forname("ClassName")
during compilation.
Aha! That explains the behaviour. I didn't realise that's why the
literal was appearing.
> There's nothing magic in log4j about using the class reference to pass
> the name, it just wants a string.
Using the literal myself is a possibility. I was just hoping not to
use a literal if i could help it to aid maintainability (given I'm
constantly renaming my classes).
Regards,
Gavin