New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@Slf4j fails with static initializer #368

Closed
lombokissues opened this Issue Jul 14, 2015 · 10 comments

Comments

Projects
None yet
4 participants
@lombokissues
Collaborator

lombokissues commented Jul 14, 2015

Migrated from Google Code (issue 295)

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 hartmut.benz   🕗 Oct 28, 2011 at 14:13 UTC

The code below produces the compile error
Cannot reference a field before it is defined
(lombok 0.10.1, eclipse 3.7.1, maven-lombok-plugin 0.10.1, Ubuntu 10.4)

Here is the code:

@ lombok.extern.slf4j.Slf4j
public class LombokTest {
static {
log.error( "Cannot reference a field before it is defined" );
}
}

Collaborator

lombokissues commented Jul 14, 2015

👤 hartmut.benz   🕗 Oct 28, 2011 at 14:13 UTC

The code below produces the compile error
Cannot reference a field before it is defined
(lombok 0.10.1, eclipse 3.7.1, maven-lombok-plugin 0.10.1, Ubuntu 10.4)

Here is the code:

@ lombok.extern.slf4j.Slf4j
public class LombokTest {
static {
log.error( "Cannot reference a field before it is defined" );
}
}

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 hartmut.benz   🕗 Oct 28, 2011 at 14:15 UTC

Oh...and java 1.6.0_26-b03

Collaborator

lombokissues commented Jul 14, 2015

👤 hartmut.benz   🕗 Oct 28, 2011 at 14:15 UTC

Oh...and java 1.6.0_26-b03

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 grootjans   🕗 Nov 07, 2011 at 19:49 UTC

Fixed in 99e36bf. Will be in next version after 0.10.2

Collaborator

lombokissues commented Jul 14, 2015

👤 grootjans   🕗 Nov 07, 2011 at 19:49 UTC

Fixed in 99e36bf. Will be in next version after 0.10.2

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 pe.fips   🕗 Nov 10, 2011 at 12:57 UTC

Sorry, but I have to reopen this issue, since your fix broke injecting of static fields in enums. See the example:

public class Issue295 {
@ lombok.Log
public enum AnEnum {
A,
B;
}

public static void main(String[] args) {
AnEnum keks = AnEnum.A;
}
}

The simple solution would be to insert the static fields after the enum constants.
We should also treat static fields in javac in the same way, so this should be done there as well.

If nobody picks this up earlier, I will provide a fix for this tomorrow.

Collaborator

lombokissues commented Jul 14, 2015

👤 pe.fips   🕗 Nov 10, 2011 at 12:57 UTC

Sorry, but I have to reopen this issue, since your fix broke injecting of static fields in enums. See the example:

public class Issue295 {
@ lombok.Log
public enum AnEnum {
A,
B;
}

public static void main(String[] args) {
AnEnum keks = AnEnum.A;
}
}

The simple solution would be to insert the static fields after the enum constants.
We should also treat static fields in javac in the same way, so this should be done there as well.

If nobody picks this up earlier, I will provide a fix for this tomorrow.

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 pe.fips   🕗 Nov 10, 2011 at 13:05 UTC

Please note that the example above compiles, but you should get an java.lang.ExceptionInInitializerError when you run it.

Collaborator

lombokissues commented Jul 14, 2015

👤 pe.fips   🕗 Nov 10, 2011 at 13:05 UTC

Please note that the example above compiles, but you should get an java.lang.ExceptionInInitializerError when you run it.

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 pe.fips   🕗 Nov 13, 2011 at 08:12 UTC

Fixed in 0d75d56.

Collaborator

lombokissues commented Jul 14, 2015

👤 pe.fips   🕗 Nov 13, 2011 at 08:12 UTC

Fixed in 0d75d56.

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 reinierz   🕗 Nov 21, 2011 at 23:02 UTC

Now in release 0.10.4

Collaborator

lombokissues commented Jul 14, 2015

👤 reinierz   🕗 Nov 21, 2011 at 23:02 UTC

Now in release 0.10.4

@lombokissues lombokissues modified the milestones: 0.10.3, 0.10.4 Jul 14, 2015

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

End of migration

Collaborator

lombokissues commented Jul 14, 2015

End of migration

@muued

This comment has been minimized.

Show comment
Hide comment
@muued

muued Mar 11, 2016

Today I tried to log something in an enum constructor which lead to a NullPointerException, because the log field was not yet initialized.
After reading this thread, it seems like trying to initialize the log field before the enum constants to be able to use it in their initialization process is not viable either.
If this is correct, it may be helpful to mention this circumstance on the feature page of the log annotation!

muued commented Mar 11, 2016

Today I tried to log something in an enum constructor which lead to a NullPointerException, because the log field was not yet initialized.
After reading this thread, it seems like trying to initialize the log field before the enum constants to be able to use it in their initialization process is not viable either.
If this is correct, it may be helpful to mention this circumstance on the feature page of the log annotation!

@tafit3

This comment has been minimized.

Show comment
Hide comment
@tafit3

tafit3 Mar 11, 2016

Static field initializers in enums execute after the initializers of enum constants. This is a java language feature, so the hint on the feature page may be useful, but your problem is out of scope of lombok.

"It is a compile-time error to reference a static field of an enum type from constructors, instance initializers, or instance variable initializer expressions of the enum type, unless the field is a constant variable (§4.12.4)."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3

However, if there is a static nested class, it will be initialized before the enum constants, so the following would work:

enum Example {
    A, B;

    private static class $LogContainer {
        static Logger log = Logger.getLogger(Example.class.getCanonicalName());
    }

    Example() {
        $LogContainer.log.info("Initializing: " + name());
    }
}

Could lombok somehow replace the "log" with "$LogContainer.log"? Another (pretty ugly) solution is to name the nested class "log" and delegate all the calls:

enum Example {
    A, B;

    private static class log {
        static Logger log = Logger.getLogger(Example.class.getCanonicalName());

        static void info(String message) {
            log.info(message);
        }
    }

    Example() {
        log.info("Initializing: " + name());
    }
}

tafit3 commented Mar 11, 2016

Static field initializers in enums execute after the initializers of enum constants. This is a java language feature, so the hint on the feature page may be useful, but your problem is out of scope of lombok.

"It is a compile-time error to reference a static field of an enum type from constructors, instance initializers, or instance variable initializer expressions of the enum type, unless the field is a constant variable (§4.12.4)."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3

However, if there is a static nested class, it will be initialized before the enum constants, so the following would work:

enum Example {
    A, B;

    private static class $LogContainer {
        static Logger log = Logger.getLogger(Example.class.getCanonicalName());
    }

    Example() {
        $LogContainer.log.info("Initializing: " + name());
    }
}

Could lombok somehow replace the "log" with "$LogContainer.log"? Another (pretty ugly) solution is to name the nested class "log" and delegate all the calls:

enum Example {
    A, B;

    private static class log {
        static Logger log = Logger.getLogger(Example.class.getCanonicalName());

        static void info(String message) {
            log.info(message);
        }
    }

    Example() {
        log.info("Initializing: " + name());
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment