2

A few days ago, I've tried to solve this SO-Question.

I know about static initializers and there benefits in java. But due to the problem I was thinking if they could be the wrong design decision if they reference a class outside of the jar.

What happened in that question?

The user tried to use CXF in his environment and failed with -

 Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.cxf.common.injection.ResourceInjector

The problem was very suspicious to me, so I asked him to add an example and I have tried to debug his example, but every time in eclipse when I was at the code where ResourceInjector was loaded, I ended up with MethodInvocation... Exception. I didn't understand the problem.

Then, another user pointed out that there is a static initializer in the cxf class:

static {
     ANNOTATIONS.add(Resource.class);
     ANNOTATIONS.add(Resources.class);
 }

Resource(s).class is from the javax.annotation package, which couldn't be found in the environment.

I think to find the problem in this issue was kinda hard, and I also think most developers would have problems to find the problem (including me).

Are static initializers with references to other jars a bad design decision?

Community
  • 1
  • 1
Martin Baumgartner
  • 3,524
  • 3
  • 20
  • 31
  • I think the point here is to enable complete stack traces so that the actual reasons for not being able to initialize a class are visibile. In case of the question you refered to this would include another nested exception with the `ClassNotFoundException` for `Resource`. So if you are able to have complete stack traces when using static initializers there is no point to worry from that perspective. – SpaceTrucker Mar 05 '15 at 08:17

2 Answers2

2

I think you are addressing wrong problem. Problem to address here will be, why did you missed the dependency?

Its fine to use a class form another jar in static initializer but then you need to ensure you package everything which is required in project.

If you are using maven for packaging, you should never face such issue.

Lokesh
  • 7,810
  • 6
  • 48
  • 78
  • 1
    Another case can be that one is assuming the dependency will be provided by the run time System (a provided dependency). Run time may or may not have the plugins installed etc. That's where `Class.forName()` checks come in. – S.D. Mar 05 '15 at 08:38
1

Interesting question. I don't see a reason why static initializers could not depend on classes from other JARs.

We have a lot of code like this:

public class MyClass {
    private static final Logger log = LoggerFactory.getLogger(MyClass.class);
    ...
}

Does it mean it is an incorrect usage? I don't think so, otherwise majority of code will be bad.

Once you are using a class, you have an effective dependency to that class. It does not really matter if it is static or not static.

Crazyjavahacking
  • 9,343
  • 2
  • 31
  • 40