On 10/4/18 3:08 PM, Luke Hutchison wrote:
If you need to read the stack in a manner that is backwards compatible with JDK 8 or earlier, there's also the following mechanism for getting the call stack, by creating a SecurityManager:

https://github.com/classgraph/classgraph/blob/master/src/main/java/io/github/classgraph/utils/CallStackReader.java

However, is there a reason to believe the above mechanism might stop working in the future?

Under what conditions might SecurityManager not allow RuntimePermission("createSecurityManager") , and how common is this likely to be?


It depends on whether the security manager is created with a doPrivileged and whether the permission is granted to the code source creating the security manager.

Will there be situations where StackWalker will succeed in reading the call stack but SecurityManager will fail, or vice versa?


SecurityManager::getClassContext is designed for the security permission check.  It's not for stack walking.

The stackwalker returns the frames it traverses and if not filtered.   SM::getClassContext is for permission check and it may filter unnecessary frames as it wishes (for example native frames as I see).

Mandy



On Thu, Oct 4, 2018 at 3:51 PM Mandy Chung <mandy.ch...@oracle.com <mailto:mandy.ch...@oracle.com>> wrote:

    If you are looking for the immediate caller, you can try
    StackWalker::getCallerClass which only walks the top few
    frames and intends to be lower cost.

    Mandy

    On 10/4/18 2:04 PM, Ralph Goers wrote:
    > Hmm, it would probably be a safe assumption that a Logger will
    never be used outside of the module. That isn’t true of the class
    name, method name and line number though. I’m not sure how much
    extra overhead there is in collecting the module name when you
    have to collect those to.
    >
    > I should add that when printing exceptions we do cache the file
    name/location as we are processing the classes for an extended
    stack trace. We probably will want to add the module name to the
    extended stack trace as well.
    >
    > Ralph
    >
    >> On Oct 4, 2018, at 10:26 AM, fo...@univ-mlv.fr
    <mailto:fo...@univ-mlv.fr> wrote:
    >>
    >> I was thinking about capturing the call stack when you create
    the logger (to get the module), not when you call the logger.
    >>
    >> cheers,
    >> Rémi
    >>
    >> ----- Mail original -----
    >>> De: "Ralph Goers" <ralph.go...@dslextreme.com
    <mailto:ralph.go...@dslextreme.com>>
    >>> À: "Alex Sviridov" <ooo_satu...@mail.ru
    <mailto:ooo_satu...@mail.ru>>
    >>> Cc: "Remi Forax" <fo...@univ-mlv.fr
    <mailto:fo...@univ-mlv.fr>>, "jigsaw-dev"
    <jigsaw-dev@openjdk.java.net <mailto:jigsaw-dev@openjdk.java.net>>
    >>> Envoyé: Mercredi 3 Octobre 2018 05:08:27
    >>> Objet: Re: Separate logging for JPMS module/layer
    >>> Log4j handles this by capturing the fully qualified class name
    of the logging
    >>> adapter. Obviously, this doesn’t work if the adapter doesn’t
    pass Log4j the
    >>> FQCN, but it does work for the adapters we support.  That
    said, it is very slow
    >>> to capture this and is probably the biggest pain point. Log4j
    recommends not
    >>> capturing this information in production environments because
    it is so slow.
    >>> Unfortunately, it seems to have gotten even slower in Java 9+.
    In an ideal
    >>> world we would be able to capture the caller information at
    compile time but
    >>> Java provides no good way to do this. Wouldn’t it be great if
    I could just code
    >>> something like logger.error(_CallerInfo_, “hello”) and the
    compiler would
    >>> provide the caller info data structure that was generated by
    the compiler?
    >>>
    >>> FWIW, I do plan to add the module information to the caller
    information provided
    >>> with Log4j but just haven’t gotten to it. You are more than
    welcome to provide
    >>> a patch.
    >>>
    >>> Ralph
    >>>
    >>>> On Oct 2, 2018, at 3:20 PM, Alex Sviridov
    <ooo_satu...@mail.ru <mailto:ooo_satu...@mail.ru>> wrote:
    >>>>
    >>>> Thank you for you suggestion. But can this be used when some
    library
    >>>> uses one logging system and for another uses some bridge.
    Because of this
    >>>> bridging
    >>>> LoggerFactory.getLogger is called somewhere in bridge, as I
    understand,
    >>>>
    >>>>
    >>>>> Среда,  3 октября 2018, 1:12 +03:00 от Remi Forax
    <fo...@univ-mlv.fr <mailto:fo...@univ-mlv.fr>>:
    >>>>>
    >>>>> You can use the StackWalker
    >>>>>
    
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StackWalker.html
    >>>>>
    >>>>> regards,
    >>>>> Rémi
    >>>>>
    >>>>> ----- Mail original -----
    >>>>>> De: "Alex Sviridov" < ooo_satu...@mail.ru
    <mailto:ooo_satu...@mail.ru> >
    >>>>>> À: "jigsaw-dev" < jigsaw-dev@openjdk.java.net
    <mailto:jigsaw-dev@openjdk.java.net> >
    >>>>>> Envoyé: Mardi 2 Octobre 2018 23:54:48
    >>>>>> Objet: Separate logging for JPMS module/layer
    >>>>>> Hi all,
    >>>>>>
    >>>>>> Could anyone say how the following problem can be solved. I
    want to create
    >>>>>> separate
    >>>>>> log file for every JPMS module/layer. The problem is that many
    >>>>>> libraries/programs
    >>>>>> use LoggerFactory.getLogger(String className) so in
    getLogger I have only
    >>>>>> the name of the class as String, so I can't get module and
    layer.
    >>>>>>
    >>>>>> If I had not String className, but Class klass then the
    problem would be easily
    >>>>>> solved.
    >>>>>> As I understand I can't load class by name because it would
    require all modules
    >>>>>> export
    >>>>>> their packages to logging framework that has no sense.
    >>>>>>
    >>>>>> Are there any solutions for such problem?
    >>>>>>
    >>>>>>
    >>>>>> --
    >>>>>> Alex Sviridov
    >>>>
    >>>> --
    >>>> Alex Sviridov
    >


Reply via email to