Link to home
Start Free TrialLog in
Avatar of keithedward
keithedward

asked on

How do you get the name of the object from within the object?

Hello,

I am not sure if I am asking this the right way... but I have java bean for a jsp page. This java bean in turn uses a logger class to log to a file... the logger class can be used in any number of beans...

I want the logger class to determine the name of the bean class that it is being class from so that it can write this to the log file ....

So if the employee bean has a logger object, then when the logger object go to write to the log, it will somehow know that it is being called from the employee class

And yes, I know jdk1.4 has a logging utility...

Thanks
Keith
Avatar of Wolfmark
Wolfmark

A simple, not so elegant solution, will be:

class Logger {
  public static void log(String message, Class caller);
  public static void log(String message, Throwable th, Class caller);
}

class MyBean {
  public void doSomething() {
    File file = new File("....");
    Logger.log("Create file object", getClass());
  }
}

I'll post other solution later. But much better.
Wolfmark
ASKER CERTIFIED SOLUTION
Avatar of Wolfmark
Wolfmark

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
And here's the modified LocationInfo class:

/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.  */

// Contributors: Mathias Rupprecht <mmathias.rupprecht@fja.com>

/**
   The internal representation of caller location information.

   @since 0.8.3
*/
class LocationInfo implements java.io.Serializable {
      public final static String LINE_SEP = System.getProperty("line.separator");
      public final static int LINE_SEP_LEN = LINE_SEP.length();

      /**
         Caller's line number.
      */
      transient String lineNumber;
      /**
         Caller's file name.
      */
      transient String fileName;
      /**
         Caller's fully qualified class name.
      */
      transient String className;
      /**
         Caller's method name.
      */
      transient String methodName;
      /**
         All available caller information, in the format
         <code>fully.qualified.classname.of.caller.methodName(Filename.java:line)</code>
        */
      public String fullInfo;

      private static StringWriter sw = new StringWriter();
      private static PrintWriter pw = new PrintWriter(sw);

      /**
         When location information is not available the constant
         <code>NA</code> is returned. Current value of this string
         constant is <b>?</b>.  */
      public final static String NA = "?";

      static final long serialVersionUID = -1325822038990805636L;

      // Check if we are running in IBM's visual age.
      static boolean inVisualAge = false;
      static {
            try {
                  Class dummy = Class.forName("com.ibm.uvm.tools.DebugSupport");
                  inVisualAge = true;
                  System.out.println("Detected IBM VisualAge environment.");
            } catch (Throwable e) {
                  // nothing to do
            }
      }

      /**
         Instantiate location information based on a Throwable. We
         expect the Throwable <code>t</code>, to be in the format
      
           <pre>
            java.lang.Throwable
            ...
              at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)
              at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)
            at org.apache.log4j.Category.callAppenders(Category.java:131)
            at org.apache.log4j.Category.log(Category.java:512)
            at callers.fully.qualified.className.methodName(FileName.java:74)
            ...
           </pre>
      
           <p>However, we can also deal with JIT compilers that "lose" the
           location information, especially between the parentheses.
      
        */
      public LocationInfo(Throwable t, String fqnOfCallingClass) {
            if (t == null)
                  return;

            String s;
            // Protect against multiple access to sw.
            synchronized (sw) {
                  t.printStackTrace(pw);
                  s = sw.toString();
                  sw.getBuffer().setLength(0);
            }
            //System.out.println("s is ["+s+"].");
            int ibegin, iend;

            // Given the current structure of the package, the line
            // containing "org.apache.log4j.Category." should be printed just
            // before the caller.

            // This method of searching may not be fastest but it's safer
            // than counting the stack depth which is not guaranteed to be
            // constant across JVM implementations.
            ibegin = s.lastIndexOf(fqnOfCallingClass);
            if (ibegin == -1)
                  return;

            ibegin = s.indexOf(LINE_SEP, ibegin);
            if (ibegin == -1)
                  return;
            ibegin += LINE_SEP_LEN;

            // determine end of line
            iend = s.indexOf(LINE_SEP, ibegin);
            if (iend == -1)
                  return;

            // VA has a different stack trace format which doesn't
            // need to skip the inital 'at'
            if (!inVisualAge) {
                  // back up to first blank character
                  ibegin = s.lastIndexOf("at ", iend);
                  if (ibegin == -1)
                        return;
                  // Add 3 to skip "at ";
                  ibegin += 3;
            }
            // everything between is the requested stack item
            this.fullInfo = s.substring(ibegin, iend);
      }

      /**
         Return the fully qualified class name of the caller making the
         logging request.
      */
      public String getClassName() {
            if (fullInfo == null)
                  return NA;
            if (className == null) {
                  // Starting the search from '(' is safer because there is
                  // potentially a dot between the parentheses.
                  int iend = fullInfo.lastIndexOf('(');
                  if (iend == -1)
                        className = NA;
                  else {
                        iend = fullInfo.lastIndexOf('.', iend);

                        // This is because a stack trace in VisualAge looks like:

                        //java.lang.RuntimeException
                        //  java.lang.Throwable()
                        //  java.lang.Exception()
                        //  java.lang.RuntimeException()
                        //  void test.test.B.print()
                        //  void test.test.A.printIndirect()
                        //  void test.test.Run.main(java.lang.String [])
                        int ibegin = 0;
                        if (inVisualAge) {
                              ibegin = fullInfo.lastIndexOf(' ', iend) + 1;
                        }

                        if (iend == -1)
                              className = NA;
                        else
                              className = this.fullInfo.substring(ibegin, iend);
                  }
            }
            return className;
      }

      /**
         Return the file name of the caller.
      
         <p>This information is not always available.
      */
      public String getFileName() {
            if (fullInfo == null)
                  return NA;

            if (fileName == null) {
                  int iend = fullInfo.lastIndexOf(':');
                  if (iend == -1)
                        fileName = NA;
                  else {
                        int ibegin = fullInfo.lastIndexOf('(', iend - 1);
                        fileName = this.fullInfo.substring(ibegin + 1, iend);
                  }
            }
            return fileName;
      }

      /**
         Returns the line number of the caller.
      
         <p>This information is not always available.
      */
      public String getLineNumber() {
            if (fullInfo == null)
                  return NA;

            if (lineNumber == null) {
                  int iend = fullInfo.lastIndexOf(')');
                  int ibegin = fullInfo.lastIndexOf(':', iend - 1);
                  if (ibegin == -1)
                        lineNumber = NA;
                  else
                        lineNumber = this.fullInfo.substring(ibegin + 1, iend);
            }
            return lineNumber;
      }

      /**
         Returns the method name of the caller.
      */
      public String getMethodName() {
            if (fullInfo == null)
                  return NA;
            if (methodName == null) {
                  int iend = fullInfo.lastIndexOf('(');
                  int ibegin = fullInfo.lastIndexOf('.', iend);
                  if (ibegin == -1)
                        methodName = NA;
                  else
                        methodName = this.fullInfo.substring(ibegin + 1, iend);
            }
            return methodName;
      }
}
use aLogger.log(Level.INFO, getClass().getName() + ": My error msg");
As I saw, you can get other many informations, like method's name, line's number, file's name.

>> And yes, I know jdk1.4 has a logging utility...

But why do you complicate your life and don't use a standard logging utility. Log4j is cool, Jdk1.4 has a framework for logging ... and if you search the net a little bit you'll find many more!
Thanx for points! :)

Other thing: if you're using Java 1.4, there is a new method named "getStackTrace" for Throwable class, which returns an array of "StackTraceElement" items. It's better than parsing the output of "printStackTrace" method. And safer!

Cheers