Derby
  1. Derby
  2. DERBY-6350

Provide a rolling file implementation of derby.log

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 10.11.1.1
    • Component/s: Miscellaneous
    • Labels:

      Description

      By default, derby.log grows without bounds if the derby.infolog.append property is set to "true". Setting this to "true" helps in a hands off production environment to ensure that if Derby restarts, the derby.log which might contain important information is not lost. On the other hand, when set the "true" the derby.log grows without bounds. This is problematic in a long running system.

      What is really needed is the ability to have a rolling derby.log file support where the maximum file size and maximum number of files can be specified. Derby has the ability to configure the location of the log file (ie. derby.stream.error.file) and also two methods of redirecting the error stream (.ie derby.stream.error.method and derby.stream.error.field). There is no standard implementation that supports a rolling derby.log however.

      This facility should be part of the core Derby system so that it works in both embedded and network server models.

      1. rollingfilelog.patch.txt
        28 kB
        Brett Bergquist
      2. rollingfilelog.patch.txt
        31 kB
        Brett Bergquist
      3. rolling_file_patch_7.diff
        44 kB
        Brett Bergquist
      4. rolling_file_patch_6.txt
        44 kB
        Brett Bergquist
      5. rolling_file_patch_5.txt
        43 kB
        Brett Bergquist
      6. ErrorStreamTest_rolling_file_cleanup.patch
        0.9 kB
        Brett Bergquist

        Issue Links

          Activity

          Hide
          Brett Bergquist added a comment -

          I have an implementation to contribute for this feature. It has the following design:

          • A RollingFileStream class that extends OutputStream that can be configured with a file pattern, file size limit, and file count, and provides the functionality to keep track how much has been written to the stream and when the max is reached, close the stream, roll the files, and reopen the stream redirected to the newest file. This is heavily borrowed from java.logger.FileHandler for the file handling capability.
          • A RollingFileStreamProvider class that provides a static method to configure and return an instance of RollingFileStream. derby.properties is consulted for the file pattern, file size limit, and file count. If these are not present, then built in defaults are used which configure the pattern such that files "derby-n.log" are created in DERBY_HOME, with the maximum file size of 1Mb and a maximum of 10 files.

          This can be plugged into the existing framework of redirecting the error stream. The derby.properties can be set as:

          derby.stream.error.method=org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream
          derby.stream.error.rollingfile.pattern=%d/db-%g.log
          derby.stream.error.rollingfile.limit=2048000
          derby.stream.error.rollingfile.count=5

          Note that the "derby.infolog.append" is still honored. If set to "false", then when Derby starts, the log files are rolled immediately and a log file is used. If set to "true", then when Derby starts, the existing newest log file (if any) is appended to.

          Show
          Brett Bergquist added a comment - I have an implementation to contribute for this feature. It has the following design: A RollingFileStream class that extends OutputStream that can be configured with a file pattern, file size limit, and file count, and provides the functionality to keep track how much has been written to the stream and when the max is reached, close the stream, roll the files, and reopen the stream redirected to the newest file. This is heavily borrowed from java.logger.FileHandler for the file handling capability. A RollingFileStreamProvider class that provides a static method to configure and return an instance of RollingFileStream. derby.properties is consulted for the file pattern, file size limit, and file count. If these are not present, then built in defaults are used which configure the pattern such that files "derby-n.log" are created in DERBY_HOME, with the maximum file size of 1Mb and a maximum of 10 files. This can be plugged into the existing framework of redirecting the error stream. The derby.properties can be set as: derby.stream.error.method=org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream derby.stream.error.rollingfile.pattern=%d/db-%g.log derby.stream.error.rollingfile.limit=2048000 derby.stream.error.rollingfile.count=5 Note that the "derby.infolog.append" is still honored. If set to "false", then when Derby starts, the log files are rolled immediately and a log file is used. If set to "true", then when Derby starts, the existing newest log file (if any) is appended to.
          Hide
          Brett Bergquist added a comment -

          Patch was missing changes to Property.java which are the constants.

          This patch implements the functionality as described.

          It is against the trunk as of 9/19/2013

          Show
          Brett Bergquist added a comment - Patch was missing changes to Property.java which are the constants. This patch implements the functionality as described. It is against the trunk as of 9/19/2013
          Hide
          Bryan Pendleton added a comment -

          Neat! I only took a quick scan of the code, but this looks very useful to me.

          Show
          Bryan Pendleton added a comment - Neat! I only took a quick scan of the code, but this looks very useful to me.
          Hide
          Rick Hillegas added a comment - - edited

          Thanks for working on this useful feature, Brett. I haven't read the patch yet. Instead, before jumping into code, I would like to agree on the developer experience, the functional spec if you will. That will help lead discussion about the code and will hopefully give Kim all the information she needs so that she can document this feature when it's integrated into the engine.

          I'll start out with a small nit: The existing Derby properties follow a camel-case convention. So I would change rollingfile to rollingFile in the new property names.

          I don't think that we need to specify the location of the rolling file implementation publicly. That, in turn, will eliminate the awkwardness of exposing an impl package in the public api. So, instead of enabling rolling logging like this...

          derby.stream.error.method=org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream

          ...I think it would be simpler to enable rolling logging like this:

          derby.stream.error=rollingFile

          I have some questions about the meaning of the other knobs:

          derby.stream.error.rollingFile.limit - Is this the maximum size of a log file before Derby rolls over to the next file in the sequence?

          derby.stream.error.rollingFile.count - Is this the maximum number of log files? If so, what happens when the maximum number of log files is exhausted? Does Derby recycle, starting over by truncating the first file in the sequence?

          The derby.stream.error.rollingFile.pattern expression syntax looks a little idiosyncratic to me. I wonder if it might be simpler to give the log files standard names (something like derby-1.log, derby-2.log, etc) and let the application specify a directory for holding the log files. The default directory could be derby.system.home/derby.log. So something like this:

          derby.stream.error.rollingFile.dir=/Users/apps/myapp/errorlog

          What are your thoughts?

          Thanks,
          -Rick

          Show
          Rick Hillegas added a comment - - edited Thanks for working on this useful feature, Brett. I haven't read the patch yet. Instead, before jumping into code, I would like to agree on the developer experience, the functional spec if you will. That will help lead discussion about the code and will hopefully give Kim all the information she needs so that she can document this feature when it's integrated into the engine. I'll start out with a small nit: The existing Derby properties follow a camel-case convention. So I would change rollingfile to rollingFile in the new property names. I don't think that we need to specify the location of the rolling file implementation publicly. That, in turn, will eliminate the awkwardness of exposing an impl package in the public api. So, instead of enabling rolling logging like this... derby.stream.error.method=org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream ...I think it would be simpler to enable rolling logging like this: derby.stream.error=rollingFile I have some questions about the meaning of the other knobs: derby.stream.error.rollingFile.limit - Is this the maximum size of a log file before Derby rolls over to the next file in the sequence? derby.stream.error.rollingFile.count - Is this the maximum number of log files? If so, what happens when the maximum number of log files is exhausted? Does Derby recycle, starting over by truncating the first file in the sequence? The derby.stream.error.rollingFile.pattern expression syntax looks a little idiosyncratic to me. I wonder if it might be simpler to give the log files standard names (something like derby-1.log, derby-2.log, etc) and let the application specify a directory for holding the log files. The default directory could be derby.system.home/derby.log. So something like this: derby.stream.error.rollingFile.dir=/Users/apps/myapp/errorlog What are your thoughts? Thanks, -Rick
          Hide
          Brett Bergquist added a comment -

          One general comment. My goal was to touch as little of the Derby code as possible to minimize the risk of introducing this. In fact, besides Property.java where the property constants are defined, there is no other code changes to Derby core. It uses the existing ability to redirect the error log. If the goal of this should be changed to make this more seamless, I don't have a problem, but again that was not my goal.

          I would have liked to have provided this as a standalone extension but a couple of things get in the way. The logging is done by the Derby core and it was desirable to locate the rolling log files in the same location as the existing derby.log. But there is no readily available way of determining the location of derby.log using the derby.stream.error.method or derby.stream.error.field facilities provided; neither of these mechanisms provide any context to use to lookup this location. The second problem is if this is indeed provided in a separate JAR, then the security policy comes into play. The invoking code of derby.stream.error.method contains a security policy in effect and being able to read system properties and write files becomes restricted by that policy. Have to change or provide a new security policy just to get rolling log files seemed to complex and cumbersome, so I made the decision that this functionality needs to be as part of the core of Derby so that the same security policy can be used.

          Kathey Marsden indicated that having the properties of configuring the rolling file in "derby.properties" was preferable to having another properties file and I agree so this also made the decision to incorporate this into Derby core.

          As for renaming the property from "rollingfile" to "rollingFile", I have no issue with this.

          As for "derby.stream.error=rollingFile", this will imply that the normal "derby.stream.error.method" and "derby.stream.error.field" cannot be used or we need to document the conflict resolution if they are. I understand that using "derby.stream.error=rollingFile" seems easier but it does make for more documentation and code changes in Derby core. I don't know if the benefit is worth the trade off.

          As for the "derby.stream.error.rollingFile.limit" and "derby.steam.error.rollingFile.count" and "derby.stream.error.rollingFile.pattern", these are directly from the "java.logger.FileHandler":

          http://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html

          with the addition of the "%d" pattern addition to represent "derby.system.home". The semantics of the file size limit and file count limit are the same as "java.logger.FileHandler" and are pretty straightforward and known to the Java community I think, so my feeling is that keeping this as similar to that is a benefit and the documentation of these can be directly lifted from that javadoc.

          Doing the changes that you suggest are possible but also seem to conflict with what is already provided by Derby. For example, the "derby.stream.error.file" specifies the location (and filename) of the output of the error stream and when this is set then the "derby.stream.error.field" and 'derby.stream.error.method" are ignored. Right there is a conflict that is documented. The "derby.stream.error.method" also has a conflict resolution with "derby.stream.error.field" that is documented.

          It seems to me that adding another "derby.stream.error" property will require updating the conflict resolution and documentation of the existing properties which is more work that I think is worth.

          Basically we are providing the user with a complete implementation that can be plugged into Derby using the standard mechanism that already exists namely the "derby.stream.error.method" with understanding that the implementation is part of Derby core and that the implementation has additional properties that can be configured through "derby.properties".

          My feeling is the simplicity of the integration using the mechanism already provided by Derby, the limit of risk in the integration into Derby core, along with the familiarity of configuration parameters that nearly match those of the "java.logger.FileHandler", and the requirement of just adding to the documentation on configuring this facility without changing or altering the existing documentation of the existing facilities is pretty important.

          I do agree with your comment on exposing and "impl" package publicly however. It does not "feel right", however, I could not find another place that "felt right" either especially with the goal of using the "derby.stream.error.method" mechanism.

          Show
          Brett Bergquist added a comment - One general comment. My goal was to touch as little of the Derby code as possible to minimize the risk of introducing this. In fact, besides Property.java where the property constants are defined, there is no other code changes to Derby core. It uses the existing ability to redirect the error log. If the goal of this should be changed to make this more seamless, I don't have a problem, but again that was not my goal. I would have liked to have provided this as a standalone extension but a couple of things get in the way. The logging is done by the Derby core and it was desirable to locate the rolling log files in the same location as the existing derby.log. But there is no readily available way of determining the location of derby.log using the derby.stream.error.method or derby.stream.error.field facilities provided; neither of these mechanisms provide any context to use to lookup this location. The second problem is if this is indeed provided in a separate JAR, then the security policy comes into play. The invoking code of derby.stream.error.method contains a security policy in effect and being able to read system properties and write files becomes restricted by that policy. Have to change or provide a new security policy just to get rolling log files seemed to complex and cumbersome, so I made the decision that this functionality needs to be as part of the core of Derby so that the same security policy can be used. Kathey Marsden indicated that having the properties of configuring the rolling file in "derby.properties" was preferable to having another properties file and I agree so this also made the decision to incorporate this into Derby core. As for renaming the property from "rollingfile" to "rollingFile", I have no issue with this. As for "derby.stream.error=rollingFile", this will imply that the normal "derby.stream.error.method" and "derby.stream.error.field" cannot be used or we need to document the conflict resolution if they are. I understand that using "derby.stream.error=rollingFile" seems easier but it does make for more documentation and code changes in Derby core. I don't know if the benefit is worth the trade off. As for the "derby.stream.error.rollingFile.limit" and "derby.steam.error.rollingFile.count" and "derby.stream.error.rollingFile.pattern", these are directly from the "java.logger.FileHandler": http://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html with the addition of the "%d" pattern addition to represent "derby.system.home". The semantics of the file size limit and file count limit are the same as "java.logger.FileHandler" and are pretty straightforward and known to the Java community I think, so my feeling is that keeping this as similar to that is a benefit and the documentation of these can be directly lifted from that javadoc. Doing the changes that you suggest are possible but also seem to conflict with what is already provided by Derby. For example, the "derby.stream.error.file" specifies the location (and filename) of the output of the error stream and when this is set then the "derby.stream.error.field" and 'derby.stream.error.method" are ignored. Right there is a conflict that is documented. The "derby.stream.error.method" also has a conflict resolution with "derby.stream.error.field" that is documented. It seems to me that adding another "derby.stream.error" property will require updating the conflict resolution and documentation of the existing properties which is more work that I think is worth. Basically we are providing the user with a complete implementation that can be plugged into Derby using the standard mechanism that already exists namely the "derby.stream.error.method" with understanding that the implementation is part of Derby core and that the implementation has additional properties that can be configured through "derby.properties". My feeling is the simplicity of the integration using the mechanism already provided by Derby, the limit of risk in the integration into Derby core, along with the familiarity of configuration parameters that nearly match those of the "java.logger.FileHandler", and the requirement of just adding to the documentation on configuring this facility without changing or altering the existing documentation of the existing facilities is pretty important. I do agree with your comment on exposing and "impl" package publicly however. It does not "feel right", however, I could not find another place that "felt right" either especially with the goal of using the "derby.stream.error.method" mechanism.
          Hide
          Rick Hillegas added a comment -

          Thanks for that explanation, Brett. I'm wondering if your problem might be solved by a more general approach which would avoid getting Derby into the business of managing the cycling of log files. Right now, the following properties can be used to configure Derby to use either a custom java.io.OutputStream or java.io.Writer:

          derby.stream.error.field
          derby.stream.error.method

          What if those methods were generalized slightly so that the custom log stream could be a java.util.logging.Logger as well? The glue code for making that work would be pretty simple I think. We might just need a new constructor for org.apache.derby.impl.services.stream.BasicHeaderPrintWriter and a small handler which wraps the diagnosticMessage in a java.util.logging.LogRecord( Level.INFO, diagnosticMessage ) entry. The cycling of log files could then be handled by the usual Java mechanisms for configuring Loggers.

          Would this give you the flexibility you need?

          Thanks,
          -Rick

          Show
          Rick Hillegas added a comment - Thanks for that explanation, Brett. I'm wondering if your problem might be solved by a more general approach which would avoid getting Derby into the business of managing the cycling of log files. Right now, the following properties can be used to configure Derby to use either a custom java.io.OutputStream or java.io.Writer: derby.stream.error.field derby.stream.error.method What if those methods were generalized slightly so that the custom log stream could be a java.util.logging.Logger as well? The glue code for making that work would be pretty simple I think. We might just need a new constructor for org.apache.derby.impl.services.stream.BasicHeaderPrintWriter and a small handler which wraps the diagnosticMessage in a java.util.logging.LogRecord( Level.INFO, diagnosticMessage ) entry. The cycling of log files could then be handled by the usual Java mechanisms for configuring Loggers. Would this give you the flexibility you need? Thanks, -Rick
          Hide
          Brett Bergquist added a comment -

          Probably not. Those methods are invoked under the security policy of Derby and any file I/O or accessing any system property is restricted by this security policy. Creating and installing a different security policy is no trivial task for most users and might not even be possible.

          I tried going this route but in my case, Derby network server is being started by the Glassfish application server. Passing in a different security policy is not supported when Glassfish starts Derby in this manner. So I was left with changing the JVM security policy or having the code within derby.jar so that it would have the same security policy of Derby.

          Note that this request has come up before but it seems nobody has actually got it to work at least not as far as I can find by searching. The standard answer is "use derby.stream.error.method or use derby.stream.error.field" but in fact this is complicated by the fact of the security policy and is not easy to implement.

          I think out of the box that Derby should support a rolling file log. Derby is supposed to be a zero administration database and having a log file grow without bounds is not zero administration, at least not to me.

          That being said, having Derby use the java.logger framework is desirable and in fact there is a JIRA for that. If it did use that framework directly (not by invoking an external piece of code that will have the security policy problem that I mention), then the user could simply configure the java.logger.FileHandler directly and all would be well. But that seems much more work in changing the Derby internals.

          Show
          Brett Bergquist added a comment - Probably not. Those methods are invoked under the security policy of Derby and any file I/O or accessing any system property is restricted by this security policy. Creating and installing a different security policy is no trivial task for most users and might not even be possible. I tried going this route but in my case, Derby network server is being started by the Glassfish application server. Passing in a different security policy is not supported when Glassfish starts Derby in this manner. So I was left with changing the JVM security policy or having the code within derby.jar so that it would have the same security policy of Derby. Note that this request has come up before but it seems nobody has actually got it to work at least not as far as I can find by searching. The standard answer is "use derby.stream.error.method or use derby.stream.error.field" but in fact this is complicated by the fact of the security policy and is not easy to implement. I think out of the box that Derby should support a rolling file log. Derby is supposed to be a zero administration database and having a log file grow without bounds is not zero administration, at least not to me. That being said, having Derby use the java.logger framework is desirable and in fact there is a JIRA for that. If it did use that framework directly (not by invoking an external piece of code that will have the security policy problem that I mention), then the user could simply configure the java.logger.FileHandler directly and all would be well. But that seems much more work in changing the Derby internals.
          Hide
          Kathey Marsden added a comment -

          Thank you Brett for adding this useful functionality. I think it will be a great relief to many users and support people.

          I wonder if we could avoid the reference to org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream by just making it so that implicit in setting any of the derby.stream.error.rollingfile properties.

          Show
          Kathey Marsden added a comment - Thank you Brett for adding this useful functionality. I think it will be a great relief to many users and support people. I wonder if we could avoid the reference to org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream by just making it so that implicit in setting any of the derby.stream.error.rollingfile properties.
          Hide
          Brett Bergquist added a comment -

          I think you are saying the same thing that Rick suggested and now there are two So I think following Rick's suggestion and use something like:

          derby.stream.error=rollingFile

          is preferrable as this will trigger the rolling file implementation. Then the properties:

          derby.stream.error.rollingFile.pattern=
          derby.stream.error.rollingFile.limit=
          derby.stream.error.rollingFile.count=

          can be used to customize the rolling file but if not present the default values will be used. Also probably another property:

          derby.stream.error.rollingFile.append=<true|false>

          which will act like the "derby.infolog.append" in that the existing log file will be append to at startup if "true" or the files will be rolled and a new log file will be created if "false" or do you think that "derby.infolog.append" is sufficient to serve as this knob?

          If we can agree on these, I will make the change and submit a patch with this change.

          Show
          Brett Bergquist added a comment - I think you are saying the same thing that Rick suggested and now there are two So I think following Rick's suggestion and use something like: derby.stream.error=rollingFile is preferrable as this will trigger the rolling file implementation. Then the properties: derby.stream.error.rollingFile.pattern= derby.stream.error.rollingFile.limit= derby.stream.error.rollingFile.count= can be used to customize the rolling file but if not present the default values will be used. Also probably another property: derby.stream.error.rollingFile.append=<true|false> which will act like the "derby.infolog.append" in that the existing log file will be append to at startup if "true" or the files will be rolled and a new log file will be created if "false" or do you think that "derby.infolog.append" is sufficient to serve as this knob? If we can agree on these, I will make the change and submit a patch with this change.
          Hide
          Dyre Tjeldvoll added a comment -

          First of all: A big THANK YOU for solving this issue!

          I understand that another patch is coming so this may not be relevant, but in the first patch I noticed that RollingFileStreamProvider.getOutputStream() swallows all exceptions and just returns null in in case of errors. Does that mean that it will silently fall back to ordinary logging or will an NPE be thrown? If it is the former, is there a way to warn about this (e.g. to stderr since logging could not be set up)? If an NPE will be thrown, I would prefer just propagating the exception (possibly wrapped in another exception type if the exception specifications are problematic).

          Show
          Dyre Tjeldvoll added a comment - First of all: A big THANK YOU for solving this issue! I understand that another patch is coming so this may not be relevant, but in the first patch I noticed that RollingFileStreamProvider.getOutputStream() swallows all exceptions and just returns null in in case of errors. Does that mean that it will silently fall back to ordinary logging or will an NPE be thrown? If it is the former, is there a way to warn about this (e.g. to stderr since logging could not be set up)? If an NPE will be thrown, I would prefer just propagating the exception (possibly wrapped in another exception type if the exception specifications are problematic).
          Hide
          Brett Bergquist added a comment -

          Right now, it does indeed swallow all errors and return null. The derby.log prints out an error indicating that the method returned "null" and the standard derby.log is used. I agree that this should do something different and will investigate this.

          Show
          Brett Bergquist added a comment - Right now, it does indeed swallow all errors and return null. The derby.log prints out an error indicating that the method returned "null" and the standard derby.log is used. I agree that this should do something different and will investigate this.
          Hide
          Brett Bergquist added a comment -

          I have implemented this as follows and will attach a patch shortly.

          I added a new property:

          derby.stream.error.style=rollingFile

          I chose this so that in the future if there is an "logger" implementation, then one could also support:

          derby.stream.error.style=logger

          When this is set to "rollingFile", then internally, this passes in "org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream" to the code that processes "derby.stream.error.method".

          So now "org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream" is not exposed to the user.

          I also modified to not catch any IOException or SecurityException in "org.apache.derby.impl.services.stream.RollingFileStreamProvider". If this occurs normal "derby.log" will be used and the error will be logged to "derby.log". This is similar as to what happens if you use "derby.stream.error.file" and point it at a file that cannot be accessed (ie. the directory does not exist for example).

          Show
          Brett Bergquist added a comment - I have implemented this as follows and will attach a patch shortly. I added a new property: derby.stream.error.style=rollingFile I chose this so that in the future if there is an "logger" implementation, then one could also support: derby.stream.error.style=logger When this is set to "rollingFile", then internally, this passes in "org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream" to the code that processes "derby.stream.error.method". So now "org.apache.derby.impl.services.stream.RollingFileStreamProvider.getOutputStream" is not exposed to the user. I also modified to not catch any IOException or SecurityException in "org.apache.derby.impl.services.stream.RollingFileStreamProvider". If this occurs normal "derby.log" will be used and the error will be logged to "derby.log". This is similar as to what happens if you use "derby.stream.error.file" and point it at a file that cannot be accessed (ie. the directory does not exist for example).
          Hide
          Brett Bergquist added a comment - - edited

          Second patch attempt. This introduces a "derby.stream.error.style" property which when set to "rollingFile" will trigger the rolling file implementation to invoked.

          This patch also removes the swallowing of any IOException or SecurityException thrown by the RollingFileStream. The exception will be propagated and the default "derby.log" implementation will be used and the error logged.

          Show
          Brett Bergquist added a comment - - edited Second patch attempt. This introduces a "derby.stream.error.style" property which when set to "rollingFile" will trigger the rolling file implementation to invoked. This patch also removes the swallowing of any IOException or SecurityException thrown by the RollingFileStream. The exception will be propagated and the default "derby.log" implementation will be used and the error logged.
          Hide
          Brett Bergquist added a comment -

          So for documentation purposes:

          derby.stream.error.style=rollingFile -> triggers the rolling file implementation and takes precedence over derby.stream.error.file or derby.stream.error.field or derby.stream.error.method

          derby.stream.error.rollingFile.pattern=<default is %d/derby-%g.log which creates files 'derby-0.log, derby-1.log, etc. in the directory where 'derby.system.home' points to>
          derby.stream.error.rollingFile.limit=<defaults to 1024000 bytes>
          derby.stream.error.rollingFile.count=<defaults to 10 files>

          Note that the "derby.infolog.append" is still honored. If set to "false", then when Derby starts, the log files are rolled immediately and a new log file is used. If set to "true", then when Derby starts, the existing newest log file (if any) is appended to.

          Show
          Brett Bergquist added a comment - So for documentation purposes: derby.stream.error.style=rollingFile -> triggers the rolling file implementation and takes precedence over derby.stream.error.file or derby.stream.error.field or derby.stream.error.method derby.stream.error.rollingFile.pattern=<default is %d/derby-%g.log which creates files 'derby-0.log, derby-1.log, etc. in the directory where 'derby.system.home' points to> derby.stream.error.rollingFile.limit=<defaults to 1024000 bytes> derby.stream.error.rollingFile.count=<defaults to 10 files> Note that the "derby.infolog.append" is still honored. If set to "false", then when Derby starts, the log files are rolled immediately and a new log file is used. If set to "true", then when Derby starts, the existing newest log file (if any) is appended to.
          Hide
          Mamta A. Satoor added a comment -

          Hi Brett, thanks for working on this useful feature. I am planning on looking at the patch soon. In the mean time, for the junit tests, you may want to look at jira DERBY-5996(Create readme files (cautioning users against modifying database files) at database hard upgrade time). In this jira, I look at the existence of the readme files. You may need something like that to make sure rolling derby.log files get created with the appropriate names. I am pretty sure I added tests to upgrade suite as well to check for the existence of readme files at hard upgrade. Is it correct that we will not create rolling log files on a soft upgrade even if user adds these properties to derby properties file? Thanks

          Show
          Mamta A. Satoor added a comment - Hi Brett, thanks for working on this useful feature. I am planning on looking at the patch soon. In the mean time, for the junit tests, you may want to look at jira DERBY-5996 (Create readme files (cautioning users against modifying database files) at database hard upgrade time). In this jira, I look at the existence of the readme files. You may need something like that to make sure rolling derby.log files get created with the appropriate names. I am pretty sure I added tests to upgrade suite as well to check for the existence of readme files at hard upgrade. Is it correct that we will not create rolling log files on a soft upgrade even if user adds these properties to derby properties file? Thanks
          Hide
          Brett Bergquist added a comment -

          Thanks for volunteering to take a look at this Mamta. I have backported it to 10.9.1.1 (my local modified copy and am using it now in production).

          I will take a look at the tests and the jira that you pointed out.

          As to your question on soft upgrade versus hard upgrade, since this introduce no change in the database at all in terms of the API, data structures, or anything else visible at that database level, only a logging facility as part of the engine, I think it should be available on a soft upgrade and I have made no coding to enforce that it not be.

          What is your thoughts on this.

          Show
          Brett Bergquist added a comment - Thanks for volunteering to take a look at this Mamta. I have backported it to 10.9.1.1 (my local modified copy and am using it now in production). I will take a look at the tests and the jira that you pointed out. As to your question on soft upgrade versus hard upgrade, since this introduce no change in the database at all in terms of the API, data structures, or anything else visible at that database level, only a logging facility as part of the engine, I think it should be available on a soft upgrade and I have made no coding to enforce that it not be. What is your thoughts on this.
          Hide
          Mamta A. Satoor added a comment -

          If we make it available in soft upgrade, I wonder if it would be confusing if the user goes back to their original version after trying out soft upgrade. They will switch from using derby.log to the new rolling logs during the soft upgrade and then back to original derby.log May be someone else in the community might have more thoughts on this.

          Show
          Mamta A. Satoor added a comment - If we make it available in soft upgrade, I wonder if it would be confusing if the user goes back to their original version after trying out soft upgrade. They will switch from using derby.log to the new rolling logs during the soft upgrade and then back to original derby.log May be someone else in the community might have more thoughts on this.
          Hide
          Kathey Marsden added a comment -

          I think it is ok for it to work in soft upgrade format. I think in general we limit the soft upgrade restriction to features that change on-disk format.

          Show
          Kathey Marsden added a comment - I think it is ok for it to work in soft upgrade format. I think in general we limit the soft upgrade restriction to features that change on-disk format.
          Hide
          Brett Bergquist added a comment -

          Note that the derby.log (and by extension the rolling log file implementation) is invoked when engine is started which is independent of a database being booted. So I don't know if "soft mode" even applies here? I think there can be log message even before any database is accessed but I could be wrong.

          Show
          Brett Bergquist added a comment - Note that the derby.log (and by extension the rolling log file implementation) is invoked when engine is started which is independent of a database being booted. So I don't know if "soft mode" even applies here? I think there can be log message even before any database is accessed but I could be wrong.
          Hide
          Mamta A. Satoor added a comment -

          Brett, may be I am doing something wrong, but in derby.properties, I only specified(I want to use the default for other associated properties)
          derby.stream.error.style=rollingFile
          But following ij session prints a NPE and there is no log file created. May be some of the other associated properties are not optional. I wonder if we throw the exception because of some problem with using the rolling log, we should print the stack trace on std err.

          $ java -Dderby.language.logQueryPlan=true -Dij.exceptionTrace=true org.apache.derby.tools.ij
          ij version 10.11
          ij> Wed Sep 25 13:23:16 PDT 2013 Thread[main,5,main] java.lang.NullPointerException
          ----------------------------------------------------------------
          Wed Sep 25 13:23:17 PDT 2013:
          Booting Derby version The Apache Software Foundation - Apache Derby - 10.11.0.0 alpha - (1): instance a816c00e-0141-56ca-3f03-000000205398
          on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@53745374
          Loaded from file:/C:/p4clients/svnmain/client3/trunk/classes/
          java.vendor=IBM Corporation
          java.runtime.version=pwi3260sr14-20130705_01 (SR14)
          java.fullversion=JRE 1.6.0 IBM J9 2.4 Windows 7 x86-32 jvmwi3260sr14-20130704_155156 (JIT enabled, AOT enabled)
          J9VM - 20130704_155156
          JIT - r9_20130517_38390
          GC - GA24_Java6_SR14_20130704_1138_B155156
          user.dir=C:\p4clients\svnmain\client3\trunk\systest\out142
          os.name=Windows 7
          os.arch=x86
          os.version=6.1 build 7601 Service Pack 1
          derby.system.home=null
          derby.stream.error.style=rollingFile
          Database Class Loader started - derby.database.classpath=''

          Show
          Mamta A. Satoor added a comment - Brett, may be I am doing something wrong, but in derby.properties, I only specified(I want to use the default for other associated properties) derby.stream.error.style=rollingFile But following ij session prints a NPE and there is no log file created. May be some of the other associated properties are not optional. I wonder if we throw the exception because of some problem with using the rolling log, we should print the stack trace on std err. $ java -Dderby.language.logQueryPlan=true -Dij.exceptionTrace=true org.apache.derby.tools.ij ij version 10.11 ij> Wed Sep 25 13:23:16 PDT 2013 Thread [main,5,main] java.lang.NullPointerException ---------------------------------------------------------------- Wed Sep 25 13:23:17 PDT 2013: Booting Derby version The Apache Software Foundation - Apache Derby - 10.11.0.0 alpha - (1): instance a816c00e-0141-56ca-3f03-000000205398 on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@53745374 Loaded from file:/C:/p4clients/svnmain/client3/trunk/classes/ java.vendor=IBM Corporation java.runtime.version=pwi3260sr14-20130705_01 (SR14) java.fullversion=JRE 1.6.0 IBM J9 2.4 Windows 7 x86-32 jvmwi3260sr14-20130704_155156 (JIT enabled, AOT enabled) J9VM - 20130704_155156 JIT - r9_20130517_38390 GC - GA24_Java6_SR14_20130704_1138_B155156 user.dir=C:\p4clients\svnmain\client3\trunk\systest\out142 os.name=Windows 7 os.arch=x86 os.version=6.1 build 7601 Service Pack 1 derby.system.home=null derby.stream.error.style=rollingFile Database Class Loader started - derby.database.classpath=''
          Hide
          Brett Bergquist added a comment -

          You are not doing anything wrong Mamta, I did something wrong. I wrongly assumed that "derby.system.home" property would always be set. The default for this uses a patter of "%d/derby-%g.log". The "%d" indicates that the rolling log file should be in the directory pointed to by 'derby.system.home' system property. I did my testing with the network server startup of derby and it seems that the embedded start as from IJ does not set this property.

          I see in your output 'derby.syste.home=null' which gave the clue.

          I will have to investigate more to determine how to reliably find where the directory where the log file should be located.

          As a test, I started IJ after setting DERBY_OPTS="-Dderby.system.home=/Users/brett/derby" and then IJ worked correctly.

          Show
          Brett Bergquist added a comment - You are not doing anything wrong Mamta, I did something wrong. I wrongly assumed that "derby.system.home" property would always be set. The default for this uses a patter of "%d/derby-%g.log". The "%d" indicates that the rolling log file should be in the directory pointed to by 'derby.system.home' system property. I did my testing with the network server startup of derby and it seems that the embedded start as from IJ does not set this property. I see in your output 'derby.syste.home=null' which gave the clue. I will have to investigate more to determine how to reliably find where the directory where the log file should be located. As a test, I started IJ after setting DERBY_OPTS="-Dderby.system.home=/Users/brett/derby" and then IJ worked correctly.
          Hide
          Brett Bergquist added a comment - - edited

          Patch attempt#3 for the rolling log file suppport. This fixes an issue when using the embedded engine which does not define "derby.system.home". This also has test implemented.

          Changes of this patch:

          1. The makeMethodHPW of the SingleStream has been modified to take a "canClose" parameter and all existing invocation paths except the one use by the rolling file implementation have been altered to pass in false. While writing the test cases, it was determined that the rolling file error stream should be closed when the derby engine shuts down. This is different from the case of derby.stream.error.method. To support such and not duplicate code, the "canClose" parameter is added so that the BasicHeaderPrintWriter can be created as closeable.

          2. The rolling file properties have their case changed to be camel case. So "derby.stream.error.rollingfile.limit" is now "derby.stream.error.rollingFile.limit", etc.

          3. RollingFileStream is changed such that if "derby.system.home" system property is not present, then "user.home" is used. This takes care of the problem when the rolling file implementation is used by the embedded engine.

          4. Tests are added:
          a) Test that "derby.stream.error.style=rollingFile" triggers the rolling file implementation
          b) Test that "derby.stream.error.style=unknownStyle" logs an error and uses the default log stream
          c) Test that "derby.stream.error.style=rollingFile" default values are respected of filenames of "derby-0.log..derby-9.log" (derby.stream.error.rollingFile.pattern=%d/derby-%g.log) and (derby.stream.error.rollingFile.count=10) and file size of 1024000 bytes (derby.stream.error.rollingFile.limit=1024000)
          d) Test that custom pattern, limit, and count are respected
          e) Test that "derby.stream.error.style=rollingFile" overrides "derby.stream.error.file", "derby.stream.error.method", "derby.stream.error.field" properties.

          One more test should be written to test the interaction of "derby.infolog.append" with "derby.stream.error.style=rollingFile" but I think these tests are enough at this point to verify the implementation.

          Show
          Brett Bergquist added a comment - - edited Patch attempt#3 for the rolling log file suppport. This fixes an issue when using the embedded engine which does not define "derby.system.home". This also has test implemented. Changes of this patch: 1. The makeMethodHPW of the SingleStream has been modified to take a "canClose" parameter and all existing invocation paths except the one use by the rolling file implementation have been altered to pass in false. While writing the test cases, it was determined that the rolling file error stream should be closed when the derby engine shuts down. This is different from the case of derby.stream.error.method. To support such and not duplicate code, the "canClose" parameter is added so that the BasicHeaderPrintWriter can be created as closeable. 2. The rolling file properties have their case changed to be camel case. So "derby.stream.error.rollingfile.limit" is now "derby.stream.error.rollingFile.limit", etc. 3. RollingFileStream is changed such that if "derby.system.home" system property is not present, then "user.home" is used. This takes care of the problem when the rolling file implementation is used by the embedded engine. 4. Tests are added: a) Test that "derby.stream.error.style=rollingFile" triggers the rolling file implementation b) Test that "derby.stream.error.style=unknownStyle" logs an error and uses the default log stream c) Test that "derby.stream.error.style=rollingFile" default values are respected of filenames of "derby-0.log..derby-9.log" (derby.stream.error.rollingFile.pattern=%d/derby-%g.log) and (derby.stream.error.rollingFile.count=10) and file size of 1024000 bytes (derby.stream.error.rollingFile.limit=1024000) d) Test that custom pattern, limit, and count are respected e) Test that "derby.stream.error.style=rollingFile" overrides "derby.stream.error.file", "derby.stream.error.method", "derby.stream.error.field" properties. One more test should be written to test the interaction of "derby.infolog.append" with "derby.stream.error.style=rollingFile" but I think these tests are enough at this point to verify the implementation.
          Hide
          Brett Bergquist added a comment -

          I had to remove the patch file. I did not add some files via SVN and the patch did not contain all of the files. I am still a newbie to this patch thing with SVN so bear with me.

          Show
          Brett Bergquist added a comment - I had to remove the patch file. I did not add some files via SVN and the patch did not contain all of the files. I am still a newbie to this patch thing with SVN so bear with me.
          Hide
          Brett Bergquist added a comment -

          rolling_file_patch_5.txt is the corrected patch file after doing an SVN add.

          I reverted all of my changes to the trunk, applied the patch, and ran the ErrorStreamTest tests and they all passed.

          Show
          Brett Bergquist added a comment - rolling_file_patch_5.txt is the corrected patch file after doing an SVN add. I reverted all of my changes to the trunk, applied the patch, and ran the ErrorStreamTest tests and they all passed.
          Hide
          Mamta A. Satoor added a comment -

          Brett, I applied the latest patch(rolling_file_patch_5.txt) and still got the same NPE in ij when I didn't have derby.system.home set. I will more testing of the patch and review the patch.

          Show
          Mamta A. Satoor added a comment - Brett, I applied the latest patch(rolling_file_patch_5.txt) and still got the same NPE in ij when I didn't have derby.system.home set. I will more testing of the patch and review the patch.
          Hide
          Mamta A. Satoor added a comment -

          If we haven't already, we should create a doc jira for this so the corresponding documentation makes its way in the docs.

          Show
          Mamta A. Satoor added a comment - If we haven't already, we should create a doc jira for this so the corresponding documentation makes its way in the docs.
          Hide
          Brett Bergquist added a comment -

          Actually I am embarrased to say that because of my issue with not doing a "svn add" of the files, I actually lost a change that I made to fix that. The lines:

          } else if (ch2 == 'd') {
          + file = new File(getSystemProperty("derby.system.home"));
          + ix++;
          + word = "";
          + continue;

          In RollingLogFileStream are the issue. I will fix that and submit a new patch in a minute.

          Show
          Brett Bergquist added a comment - Actually I am embarrased to say that because of my issue with not doing a "svn add" of the files, I actually lost a change that I made to fix that. The lines: } else if (ch2 == 'd') { + file = new File(getSystemProperty("derby.system.home")); + ix++; + word = ""; + continue; In RollingLogFileStream are the issue. I will fix that and submit a new patch in a minute.
          Hide
          Brett Bergquist added a comment -

          Fixed NPE when "derby.system.home" is not defined. In that case the "user.dir" property is used to determine the location for the log files.

          Show
          Brett Bergquist added a comment - Fixed NPE when "derby.system.home" is not defined. In that case the "user.dir" property is used to determine the location for the log files.
          Hide
          Kim Haase added a comment -

          I can file a doc issue. Please stay tuned.

          Show
          Kim Haase added a comment - I can file a doc issue. Please stay tuned.
          Hide
          Brett Bergquist added a comment -

          I need to add a test for "derby.system.home" not being defined as part of the ErrorStreamTests.

          Show
          Brett Bergquist added a comment - I need to add a test for "derby.system.home" not being defined as part of the ErrorStreamTests.
          Hide
          Mamta A. Satoor added a comment -

          If I give incorrect value for
          derby.stream.error.style=rollingFile1
          I get NPE when connecting to a database through ij
          $ java -Dderby.language.logQueryPlan=true -Dderby.system.home="C:\p4clients\svnmain\client3\trunk\systest\out142" -Dij.exceptionTrace=true org.apache.derby.tools.ij
          ij version 10.11
          ij> connect 'jdbc:derby:db1;create=true';
          Mon Sep 30 13:18:12 PDT 2013 Thread[main,5,main] java.lang.IllegalArgumentException: unknown derby.stream.error.style: rollingFile1
          ----------------------------------------------------------------
          Mon Sep 30 13:18:12 PDT 2013:
          Booting Derby version The Apache Software Foundation - Apache Derby - 10.11.0.0 alpha - (1): instance a816c00e-0141-7085-65ee-000073edb42f
          on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@538b538b
          Loaded from file:/C:/p4clients/svnmain/client3/trunk/classes/
          java.vendor=IBM Corporation
          java.runtime.version=pwi3260sr14-20130705_01 (SR14)
          java.fullversion=JRE 1.6.0 IBM J9 2.4 Windows 7 x86-32 jvmwi3260sr14-20130704_155156 (JIT enabled, AOT enabled)
          J9VM - 20130704_155156
          JIT - r9_20130517_38390
          GC - GA24_Java6_SR14_20130704_1138_B155156
          user.dir=C:\p4clients\svnmain\client3\trunk\systest\out142
          os.name=Windows 7
          os.arch=x86
          os.version=6.1 build 7601 Service Pack 1
          derby.system.home=C:\p4clients\svnmain\client3\trunk\systest\out142
          derby.stream.error.style=rollingFile1
          Database Class Loader started - derby.database.classpath=''
          WARNING 01J01: Database 'db1' not created, connection made to existing database instead.
          ij> exit;
          ----------------------------------------------------------------
          Mon Sep 30 13:18:35 PDT 2013: Shutting down Derby engine
          ----------------------------------------------------------------
          Mon Sep 30 13:18:35 PDT 2013:
          Shutting down instance a816c00e-0141-7085-65ee-000073edb42f on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@538b538b
          ----------------------------------------------------------------

          Show
          Mamta A. Satoor added a comment - If I give incorrect value for derby.stream.error.style=rollingFile1 I get NPE when connecting to a database through ij $ java -Dderby.language.logQueryPlan=true -Dderby.system.home="C:\p4clients\svnmain\client3\trunk\systest\out142" -Dij.exceptionTrace=true org.apache.derby.tools.ij ij version 10.11 ij> connect 'jdbc:derby:db1;create=true'; Mon Sep 30 13:18:12 PDT 2013 Thread [main,5,main] java.lang.IllegalArgumentException: unknown derby.stream.error.style: rollingFile1 ---------------------------------------------------------------- Mon Sep 30 13:18:12 PDT 2013: Booting Derby version The Apache Software Foundation - Apache Derby - 10.11.0.0 alpha - (1): instance a816c00e-0141-7085-65ee-000073edb42f on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@538b538b Loaded from file:/C:/p4clients/svnmain/client3/trunk/classes/ java.vendor=IBM Corporation java.runtime.version=pwi3260sr14-20130705_01 (SR14) java.fullversion=JRE 1.6.0 IBM J9 2.4 Windows 7 x86-32 jvmwi3260sr14-20130704_155156 (JIT enabled, AOT enabled) J9VM - 20130704_155156 JIT - r9_20130517_38390 GC - GA24_Java6_SR14_20130704_1138_B155156 user.dir=C:\p4clients\svnmain\client3\trunk\systest\out142 os.name=Windows 7 os.arch=x86 os.version=6.1 build 7601 Service Pack 1 derby.system.home=C:\p4clients\svnmain\client3\trunk\systest\out142 derby.stream.error.style=rollingFile1 Database Class Loader started - derby.database.classpath='' WARNING 01J01: Database 'db1' not created, connection made to existing database instead. ij> exit; ---------------------------------------------------------------- Mon Sep 30 13:18:35 PDT 2013: Shutting down Derby engine ---------------------------------------------------------------- Mon Sep 30 13:18:35 PDT 2013: Shutting down instance a816c00e-0141-7085-65ee-000073edb42f on database directory C:\p4clients\svnmain\client3\trunk\systest\out142\db1 with class loader sun.misc.Launcher$AppClassLoader@538b538b ----------------------------------------------------------------
          Hide
          Brett Bergquist added a comment -

          Do you get a NPE or is it you get the IllegalArgumentException shown in your output. This is code explicitly to throw an IllegalArgumentException if the style is not recognized. We can do something different but I don't know what should be done in that case. Note that there is also a test in ErrorStreamTest.java for this as well.

          Show
          Brett Bergquist added a comment - Do you get a NPE or is it you get the IllegalArgumentException shown in your output. This is code explicitly to throw an IllegalArgumentException if the style is not recognized. We can do something different but I don't know what should be done in that case. Note that there is also a test in ErrorStreamTest.java for this as well.
          Hide
          Mamta A. Satoor added a comment - - edited

          After applying the 6th patch, I get IllegalArgumentException. With patch 5, I got NPE. I think in case a like this, we should revert to using traditional derby.log after giving a warning on system.out and derby.log. Just a thought. I think this is the behavior you noted in an earlier comment
          "Test that "derby.stream.error.style=unknownStyle" logs an error and uses the default log stream"

          Show
          Mamta A. Satoor added a comment - - edited After applying the 6th patch, I get IllegalArgumentException. With patch 5, I got NPE. I think in case a like this, we should revert to using traditional derby.log after giving a warning on system.out and derby.log. Just a thought. I think this is the behavior you noted in an earlier comment "Test that "derby.stream.error.style=unknownStyle" logs an error and uses the default log stream"
          Hide
          Brett Bergquist added a comment -

          Manta, can you review the code in SingleStream.java, lines 261-278. I tried to follow the model when using "derby.stream.error.method=xxx" fails. So that code is throwing an IllegalArgumentException with the error message and catching the error (to get the stack traceback) and then calling useDefaultStream with the caught exception.

          So I think this should be correct and should use the "derby.log" when you use an invalid "style". From your IJ output earlier it looks like (with patch 6) that it output the error and continued.

          Also if you could review ErrorStreamTest.java, lines 393-408. this is checking for an unknown style and checking to see if the errStreamFile is not empty. Maybe this needs to also test the derby.log is not empty but this code was modeled on the "testWrongMethod" test in the same file.

          Show
          Brett Bergquist added a comment - Manta, can you review the code in SingleStream.java, lines 261-278. I tried to follow the model when using "derby.stream.error.method=xxx" fails. So that code is throwing an IllegalArgumentException with the error message and catching the error (to get the stack traceback) and then calling useDefaultStream with the caught exception. So I think this should be correct and should use the "derby.log" when you use an invalid "style". From your IJ output earlier it looks like (with patch 6) that it output the error and continued. Also if you could review ErrorStreamTest.java, lines 393-408. this is checking for an unknown style and checking to see if the errStreamFile is not empty. Maybe this needs to also test the derby.log is not empty but this code was modeled on the "testWrongMethod" test in the same file.
          Hide
          Mamta A. Satoor added a comment -

          Brett, I debugged through SingleStream.java and see if that in case of IllegalArgumentException, we call useDefaultStream as you pointed out. But useDefaultStream uses System.err to log the info.
          return new BasicHeaderPrintWriter(System.err, header, false, "System.err");
          I wonder in this case, if we should be calling createDefaultStream which uses derby.log. If we do use createDefaultStream. Once we have the HeaderPrintWriter for derby.log, we can call printlnWithHeader to log the IllegalArgumentException.

          If we do make the above change, then I think we will need to check for errStreamFile to be empty and derby.log to be not empty.

          Show
          Mamta A. Satoor added a comment - Brett, I debugged through SingleStream.java and see if that in case of IllegalArgumentException, we call useDefaultStream as you pointed out. But useDefaultStream uses System.err to log the info. return new BasicHeaderPrintWriter(System.err, header, false, "System.err"); I wonder in this case, if we should be calling createDefaultStream which uses derby.log. If we do use createDefaultStream. Once we have the HeaderPrintWriter for derby.log, we can call printlnWithHeader to log the IllegalArgumentException. If we do make the above change, then I think we will need to check for errStreamFile to be empty and derby.log to be not empty.
          Hide
          Brett Bergquist added a comment -

          Mamta, the other properties also use "useDefaultStream". For example, if "derby.stream.error.field" fails, it calls "useDefaultStream", similarly if "derby.stream.error.method" fails, it calls "userDefaultStream" and finally if "derby.stream.error.file" fails, it also calls "useDefaultStream".

          So should this be any different? I think if this should call "createDefautStream" then the other methods should as well. If not, then this should be consistent with those. And in any case, if specified wrong I think it will be immediately recognized and corrected.

          At this point I would rather not change this but of course I will go with what ever is decided.

          Show
          Brett Bergquist added a comment - Mamta, the other properties also use "useDefaultStream". For example, if "derby.stream.error.field" fails, it calls "useDefaultStream", similarly if "derby.stream.error.method" fails, it calls "userDefaultStream" and finally if "derby.stream.error.file" fails, it also calls "useDefaultStream". So should this be any different? I think if this should call "createDefautStream" then the other methods should as well. If not, then this should be consistent with those. And in any case, if specified wrong I think it will be immediately recognized and corrected. At this point I would rather not change this but of course I will go with what ever is decided.
          Hide
          Mamta A. Satoor added a comment -

          Brett, I am fine with the current patch's behavior unless someone else in the community feels otherwise. I do not think we want to change the behavior of other existing properties.

          Show
          Mamta A. Satoor added a comment - Brett, I am fine with the current patch's behavior unless someone else in the community feels otherwise. I do not think we want to change the behavior of other existing properties.
          Hide
          Brett Bergquist added a comment -

          What is the next step for this patch? Is it appear to be ready to be committed?

          Show
          Brett Bergquist added a comment - What is the next step for this patch? Is it appear to be ready to be committed?
          Hide
          Mamta A. Satoor added a comment -

          Brett, I can commit the patch early next week if there are no further comments from the community. Thanks for working on this valuable feature.

          Show
          Mamta A. Satoor added a comment - Brett, I can commit the patch early next week if there are no further comments from the community. Thanks for working on this valuable feature.
          Hide
          Mamta A. Satoor added a comment -

          It will be a good idea to run the entire junit test suite with these knobs to see if they run fine with rolling log. I am not sure at this point how to do it, may be as JVM properties when starting the tests or may be as a separate suite.

          Show
          Mamta A. Satoor added a comment - It will be a good idea to run the entire junit test suite with these knobs to see if they run fine with rolling log. I am not sure at this point how to do it, may be as JVM properties when starting the tests or may be as a separate suite.
          Hide
          Myrna van Lunteren added a comment -

          I thought of running the entire junit test suite by wrapping the class AllPackages in a SystemPropertyTestSetup, but I thought I'd first at least run the now much bigger ErrorStreamTest.

          Unfortunately that gives me 4 errors on my Windows 7 box:

          1) testStyleRollingFile(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\derby-0.log could not be deleted
          at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testStyleRollingFile(ErrorStreamTest.java:387)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)

          And then 3 more that are probably happening as a result of the previous one:
          2) testWrongStyle(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: C:\tst\d6350\errortst\system\derby-0.log exists
          at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.assertNotExisting(ErrorStreamTest.java:697)
          at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testWrongStyle(ErrorStreamTest.java:403)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
          3) testDefaultRollingDefaultConfig(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\derby-0.log could not be deleted
          at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testDefaultRollingDefaultConfig(ErrorStreamTest.java:446)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
          4) testDefaultRollingUserConfig(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\db-0.log could not be deleted
          at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testDefaultRollingUserConfig(ErrorStreamTest.java:498)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
          at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)

          I will take a closer look at the test, see if I understand these failures.

          Show
          Myrna van Lunteren added a comment - I thought of running the entire junit test suite by wrapping the class AllPackages in a SystemPropertyTestSetup, but I thought I'd first at least run the now much bigger ErrorStreamTest. Unfortunately that gives me 4 errors on my Windows 7 box: 1) testStyleRollingFile(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\derby-0.log could not be deleted at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testStyleRollingFile(ErrorStreamTest.java:387) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456) And then 3 more that are probably happening as a result of the previous one: 2) testWrongStyle(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: C:\tst\d6350\errortst\system\derby-0.log exists at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.assertNotExisting(ErrorStreamTest.java:697) at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testWrongStyle(ErrorStreamTest.java:403) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456) 3) testDefaultRollingDefaultConfig(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\derby-0.log could not be deleted at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testDefaultRollingDefaultConfig(ErrorStreamTest.java:446) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456) 4) testDefaultRollingUserConfig(org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest)junit.framework.AssertionFailedError: File C:\tst\d6350\errortst\system\db-0.log could not be deleted at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testDefaultRollingUserConfig(ErrorStreamTest.java:498) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456) I will take a closer look at the test, see if I understand these failures.
          Hide
          Brett Bergquist added a comment -

          Sorry, I have been on vacation. I will get access to a Windows box early next week and try to determine why the files are not being closed.

          Show
          Brett Bergquist added a comment - Sorry, I have been on vacation. I will get access to a Windows box early next week and try to determine why the files are not being closed.
          Hide
          Myrna van Lunteren added a comment - - edited

          I've not had a chance to further investigate either, except to say that there are 3 fixtures/methods that suffer from this behavior:
          testStyleRollingFile()
          testDefaultRollingDefaultConfig()
          testDefaultRollingUserConfig()
          (so the other failures were cascading from this).

          I prevented these 3 fixtures from running (by renaming the methods to start with 'xtest' instead of 'test'), and ErrorStreamTest passed, and the engine._Suite suite passed also.

          Windows is pickier about deleting files that have been accessed, we've seen that before, so this could just be a test cleanup issue...

          Show
          Myrna van Lunteren added a comment - - edited I've not had a chance to further investigate either, except to say that there are 3 fixtures/methods that suffer from this behavior: testStyleRollingFile() testDefaultRollingDefaultConfig() testDefaultRollingUserConfig() (so the other failures were cascading from this). I prevented these 3 fixtures from running (by renaming the methods to start with 'xtest' instead of 'test'), and ErrorStreamTest passed, and the engine._Suite suite passed also. Windows is pickier about deleting files that have been accessed, we've seen that before, so this could just be a test cleanup issue...
          Hide
          Mike Matrigali added a comment -

          to expand on what myrna pointed out. The main difference in this area that we see between unix and windows is that windows does not
          allow a file to be deleted that is currently open. So suggest you look for missing closes of the files.

          Another safety check might be to by hand to the following test:
          o set up the system that is creates a large number of derby.logs in a single test run, and then use the unix tools to show
          open files. I think the goal would be only ever one derby.log segment open at one time (or maybe an edge case of 2 or something
          like that). We sometimes run into open file issues on derby, so 1 at a time would be a good goal or we may have to point it out
          in a release note. There are some applications out there that have large number of databases in their application and are sensitive
          to any per-database increase in resources like open files, system threads, size, ...

          Show
          Mike Matrigali added a comment - to expand on what myrna pointed out. The main difference in this area that we see between unix and windows is that windows does not allow a file to be deleted that is currently open. So suggest you look for missing closes of the files. Another safety check might be to by hand to the following test: o set up the system that is creates a large number of derby.logs in a single test run, and then use the unix tools to show open files. I think the goal would be only ever one derby.log segment open at one time (or maybe an edge case of 2 or something like that). We sometimes run into open file issues on derby, so 1 at a time would be a good goal or we may have to point it out in a release note. There are some applications out there that have large number of databases in their application and are sensitive to any per-database increase in resources like open files, system threads, size, ...
          Hide
          Brett Bergquist added a comment -

          This patch closes the underlying stream which was missing. All the junit tests now run cleanly on both unix based (MAC) and Windows.

          Show
          Brett Bergquist added a comment - This patch closes the underlying stream which was missing. All the junit tests now run cleanly on both unix based (MAC) and Windows.
          Hide
          Mamta A. Satoor added a comment -

          Brett, I will apply your latest patch and run the junit tests on my machine.

          I had used the earlier patch to run the junit suite with rollingFile(as shown below)
          time java -Dderby.stream.error.style=rollingFile -Dderby.tests.trace=true junit.textui.TestRunner org.apache.derbyTesting.functionTests.suites.All > runall.out 2>&1
          and saw the failure noticed by Myrna. Additionally, I saw that even though we are running junit suite with the rollingFile, we still created derby.log(although it was empty) along with expected derby-0.log and so on. I had not expected to see the traditional derby.log when running with rollingFile. In addition, when a test failed, the failed directory had empty derby.log copied but the rolling log files did not get copied. The code changes to copy the rolling log files in case of failure probably need to go into org.apache.derbyTesting.junit.BaseTestCase:runBare() in the "catch (Throwable running) {" section. I can open a new jira for this and link it this jira.

          Show
          Mamta A. Satoor added a comment - Brett, I will apply your latest patch and run the junit tests on my machine. I had used the earlier patch to run the junit suite with rollingFile(as shown below) time java -Dderby.stream.error.style=rollingFile -Dderby.tests.trace=true junit.textui.TestRunner org.apache.derbyTesting.functionTests.suites.All > runall.out 2>&1 and saw the failure noticed by Myrna. Additionally, I saw that even though we are running junit suite with the rollingFile, we still created derby.log(although it was empty) along with expected derby-0.log and so on. I had not expected to see the traditional derby.log when running with rollingFile. In addition, when a test failed, the failed directory had empty derby.log copied but the rolling log files did not get copied. The code changes to copy the rolling log files in case of failure probably need to go into org.apache.derbyTesting.junit.BaseTestCase:runBare() in the "catch (Throwable running) {" section. I can open a new jira for this and link it this jira.
          Hide
          Brett Bergquist added a comment -

          In regards to the empty "derby.log" when using the rollingFile implemenation, this occurs because of BaseMonitor.boot calling SingleStream.boot. This occurs when Derby is started, long before it looks for any properties. I tis called by ErrorStreamTest.setup/ErrrorStreamTest.bootDerby, etc.

          So i don't think anything can be done about the "derby.log" being created and in fact I think it is probably risky to make any changes there. In my opinion I think it is okay the way that it is.

          I believe that this same issue will be present if you use the "derby.stream.error.file" property or the "derby.stream.error.field" property, or the "derby.stream.error.method" properties as well. In fact, just testing now and during the ErrorStreamTest.testFile method by itself, it also has a "derby.log" present.

          Show
          Brett Bergquist added a comment - In regards to the empty "derby.log" when using the rollingFile implemenation, this occurs because of BaseMonitor.boot calling SingleStream.boot. This occurs when Derby is started, long before it looks for any properties. I tis called by ErrorStreamTest.setup/ErrrorStreamTest.bootDerby, etc. So i don't think anything can be done about the "derby.log" being created and in fact I think it is probably risky to make any changes there. In my opinion I think it is okay the way that it is. I believe that this same issue will be present if you use the "derby.stream.error.file" property or the "derby.stream.error.field" property, or the "derby.stream.error.method" properties as well. In fact, just testing now and during the ErrorStreamTest.testFile method by itself, it also has a "derby.log" present.
          Hide
          Myrna van Lunteren added a comment - - edited

          I agree - the derby.log file creation is not something that's under control of the ErrorStreamTest, it is something related to our junit framework and basic derby operation as Brett identified rather than this feature.

          I ran the engine._Suite (which includes the new test fixtures) with patch _7 applied, and it now indeed passes on my windows machine.
          Further improvements can be done separately, (under separate JIRAs, like what Mamta found for failure analysis of DERBY-6380), I think this feature is now ready to go in.

          +1 to commit.

          Show
          Myrna van Lunteren added a comment - - edited I agree - the derby.log file creation is not something that's under control of the ErrorStreamTest, it is something related to our junit framework and basic derby operation as Brett identified rather than this feature. I ran the engine._Suite (which includes the new test fixtures) with patch _7 applied, and it now indeed passes on my windows machine. Further improvements can be done separately, (under separate JIRAs, like what Mamta found for failure analysis of DERBY-6380 ), I think this feature is now ready to go in. +1 to commit.
          Hide
          Mamta A. Satoor added a comment -

          I will work on committing the patch soon unless someone has any comments. The junit tests have not finished on my machine yet.

          Show
          Mamta A. Satoor added a comment - I will work on committing the patch soon unless someone has any comments. The junit tests have not finished on my machine yet.
          Hide
          Myrna van Lunteren added a comment -

          I think this should not hold up initial commit, but perhaps we can modify the code later so that if the rolling log file properties are set, we just delete the newly created derby.log (if it is indeed empty)?

          Show
          Myrna van Lunteren added a comment - I think this should not hold up initial commit, but perhaps we can modify the code later so that if the rolling log file properties are set, we just delete the newly created derby.log (if it is indeed empty)?
          Hide
          Mamta A. Satoor added a comment -

          derbyall and junit ran fine on machine with the patch

          Show
          Mamta A. Satoor added a comment - derbyall and junit ran fine on machine with the patch
          Hide
          ASF subversion and git services added a comment -

          Commit 1533320 from Mamta A. Satoor in branch 'code/trunk'
          [ https://svn.apache.org/r1533320 ]

          DERBY-6350 (Provide a rolling file implementation of derby.log)

          Committing patch submitted by Brett Bergquist

          Show
          ASF subversion and git services added a comment - Commit 1533320 from Mamta A. Satoor in branch 'code/trunk' [ https://svn.apache.org/r1533320 ] DERBY-6350 (Provide a rolling file implementation of derby.log) Committing patch submitted by Brett Bergquist
          Hide
          Knut Anders Hatlen added a comment -

          There was a failure in one of the new test cases in the latest nightly test cycle:
          http://download.java.net/javadesktop/derby/request_5583094/javadb-task-3745053.html

          junit.framework.AssertionFailedError: /localhome/tendril4.2/work/run/27530881/junit/system/derby-0.log exists
          	at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.assertNotExisting(ErrorStreamTest.java:697)
          	at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testWrongStyle(ErrorStreamTest.java:403)
          	at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          	at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
          	at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
          
          Show
          Knut Anders Hatlen added a comment - There was a failure in one of the new test cases in the latest nightly test cycle: http://download.java.net/javadesktop/derby/request_5583094/javadb-task-3745053.html junit.framework.AssertionFailedError: /localhome/tendril4.2/work/run/27530881/junit/system/derby-0.log exists at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.assertNotExisting(ErrorStreamTest.java:697) at org.apache.derbyTesting.functionTests.tests.engine.ErrorStreamTest.testWrongStyle(ErrorStreamTest.java:403) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439) at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
          Hide
          Brett Bergquist added a comment -

          Are the test cases always run in the same order? I am not totally familiar with this and maybe a derby-0.log was present from another test case, causing this to fail?

          Show
          Brett Bergquist added a comment - Are the test cases always run in the same order? I am not totally familiar with this and maybe a derby-0.log was present from another test case, causing this to fail?
          Hide
          Knut Anders Hatlen added a comment -

          The test cases could run in any order (there are techniques to force them to run in a specific order, though). So it would be best if each test case cleaned up after itself completely. The failing test run executed the test cases in the following order:

          testMethod
          testFile
          testFileOverMethod
          testFileOverField
          testMethodOverField
          testStyleRollingFile
          testRollingFileStyleOverFile
          testRollingFileStyleOverMethod
          testRollingFileStyleOverField
          testDefault
          testWrongFile
          testWrongMethod
          testField
          testWrongField
          testWrongStyle
          testFileOverMethodAndField
          testDefaultRollingDefaultConfig
          testDefaultRollingUserConfig

          Show
          Knut Anders Hatlen added a comment - The test cases could run in any order (there are techniques to force them to run in a specific order, though). So it would be best if each test case cleaned up after itself completely. The failing test run executed the test cases in the following order: testMethod testFile testFileOverMethod testFileOverField testMethodOverField testStyleRollingFile testRollingFileStyleOverFile testRollingFileStyleOverMethod testRollingFileStyleOverField testDefault testWrongFile testWrongMethod testField testWrongField testWrongStyle testFileOverMethodAndField testDefaultRollingDefaultConfig testDefaultRollingUserConfig
          Hide
          Brett Bergquist added a comment -

          Okay, thanks. Did not know that and probably one of the tests is not cleaning up. I will take a look at it.

          Show
          Brett Bergquist added a comment - Okay, thanks. Did not know that and probably one of the tests is not cleaning up. I will take a look at it.
          Hide
          Brett Bergquist added a comment -

          Here is a patch for ErrorStreamTest.java. This patch removes the rolling log files created by two test cases to ensure that the test cases can be run in any order.

          Show
          Brett Bergquist added a comment - Here is a patch for ErrorStreamTest.java. This patch removes the rolling log files created by two test cases to ensure that the test cases can be run in any order.
          Hide
          Mamta A. Satoor added a comment -

          Brett, the patch looks good. I will commit it.

          Show
          Mamta A. Satoor added a comment - Brett, the patch looks good. I will commit it.
          Hide
          Mamta A. Satoor added a comment -

          Just realized that the commit has not shown up in jira for some reason. The test changes went in on Tue Oct 29th 2013 as part of revision 1536808.

          Show
          Mamta A. Satoor added a comment - Just realized that the commit has not shown up in jira for some reason. The test changes went in on Tue Oct 29th 2013 as part of revision 1536808.
          Hide
          Myrna van Lunteren added a comment -

          I did some simple manual experimenting, and did not see an empty derby.log created. But I do see it when running the ErrorStreamsTest. I'll do a little more analysis, and if I figure out what the problem is I'll log a new issue.
          But I think this can be resolved.

          Show
          Myrna van Lunteren added a comment - I did some simple manual experimenting, and did not see an empty derby.log created. But I do see it when running the ErrorStreamsTest. I'll do a little more analysis, and if I figure out what the problem is I'll log a new issue. But I think this can be resolved.
          Hide
          Myrna van Lunteren added a comment -

          Thanks for contributing this feature Brett!

          Show
          Myrna van Lunteren added a comment - Thanks for contributing this feature Brett!
          Hide
          Myrna van Lunteren added a comment -

          bulk change to close all issues resolved but not closed and not changed since June 1, 2014.

          Show
          Myrna van Lunteren added a comment - bulk change to close all issues resolved but not closed and not changed since June 1, 2014.

            People

            • Assignee:
              Brett Bergquist
              Reporter:
              Brett Bergquist
            • Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development