Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8172274

Unexpected logging message to standard output

XMLWordPrintable

    • generic
    • generic

      A DESCRIPTION OF THE REQUEST :
      On Wed April 9, 2014, it appears the following code was checked in against com/sun/javafx/scene/control/skin/VirtualFlow.java:

                          final PlatformLogger logger = Logging.getControlsLogger();
                          if (logger.isLoggable(PlatformLogger.Level.INFO)) {
                              if (startCell != null) {
                                  logger.info("index exceeds maxCellCount. Check size calculations for " + startCell.getClass());
                              } else {
                                  logger.info("index exceeds maxCellCount");
                              }
                          }


      JUSTIFICATION :
      By having the logger write to standard output (or standard error), it violates the principle of least astonishment. An application that potentially uses standard output for its own purposes, in a specific format, could cause an unexpected failure due to this logging statement.

      Without accidentally stumbling across this informational message, there is no way to know that it would be written in a production system. If an application does not have logging configured, it is expected that no logging will be written.

      This logging message has caught a few people by surprise (as per their StackOverflow questions. Moreover, it should not be exposed to end users, which is the likely scenario since there's no feasible way for a developer to know that the code was even written to log to the console.

      See also:

      * http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8089472
      * http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8140504

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Since this is merely a warning, it seems the code can be safely removed, or an exception declared and thrown in its place. There should be nothing written to standard output or standard error. Logging should be completely disabled by default, unless the application explicitly enables logging.
      ACTUAL -
      The following text is logged to standard error:

      Jan 04, 2017 6:16:11 PM com.sun.javafx.scene.control.skin.VirtualFlow addTrailingCells
      INFO: index exceeds maxCellCount. Check size calculations for class javafx.scene.control.TableRow


      ---------- BEGIN SOURCE ----------
      Compile, run, then click the "Add" button to see the result.

      import javafx.application.*;
      import javafx.stage.*;
      import javafx.scene.*;
      import javafx.scene.control.*;
      import javafx.scene.control.cell.*;
      import javafx.scene.layout.*;
      import javafx.beans.property.*;
      import javafx.collections.*;

      public class TableViewSample extends Application {

          private TableView<Person> table = new TableView<Person>();
          private final ObservableList<Person> data = FXCollections.observableArrayList();

          public static void main(String[] args) {
              launch(args);
          }

          @Override
          public void start(Stage stage) {
              Scene scene = new Scene(new Group());
              stage.setTitle("Table View Sample");
              stage.setWidth(450);
              stage.setHeight(500);

              table.setEditable(true);

              TableColumn firstNameCol = new TableColumn("First Name");
              firstNameCol.setMinWidth(100);
              firstNameCol.setCellValueFactory(
                      new PropertyValueFactory<Person, String>("firstName"));

              TableColumn lastNameCol = new TableColumn("Last Name");
              lastNameCol.setMinWidth(100);
              lastNameCol.setCellValueFactory(
                      new PropertyValueFactory<Person, String>("lastName"));

              TableColumn emailCol = new TableColumn("Email");
              emailCol.setMinWidth(200);
              emailCol.setCellValueFactory(
                      new PropertyValueFactory<Person, String>("email"));

              table.setItems(data);
              table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

              // -------------------------------
              // dynamically add data
              // -------------------------------

              // fill table with data
              for( int i=0; i < 14; i++) {
                  Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
                  data.add( person);
              }

              // button to add new data
              Button bt = new Button( "Add");
              bt.setOnAction(e -> {

                  // insert new item
                  int i = data.size() + 1;
                  Person person = new Person( "Name " + i, "Name " + i, "Mail " + i);
                  data.add( person);

                  // scroll to new item
                  table.scrollTo( person);

              });

              // -------------------------------

              final VBox vbox = new VBox();
              vbox.setSpacing(5);
              vbox.getChildren().addAll(table, bt);

              ((Group) scene.getRoot()).getChildren().addAll(vbox);

              stage.setScene(scene);
              stage.show();


          }

          public static class Person {

              private final SimpleStringProperty firstName;
              private final SimpleStringProperty lastName;
              private final SimpleStringProperty email;

              private Person(String fName, String lName, String email) {
                  this.firstName = new SimpleStringProperty(fName);
                  this.lastName = new SimpleStringProperty(lName);
                  this.email = new SimpleStringProperty(email);
              }

              public String getFirstName() {
                  return firstName.get();
              }

              public void setFirstName(String fName) {
                  firstName.set(fName);
              }

              public String getLastName() {
                  return lastName.get();
              }

              public void setLastName(String fName) {
                  lastName.set(fName);
              }

              public String getEmail() {
                  return email.get();
              }

              public void setEmail(String fName) {
                  email.set(fName);
              }
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      A work around would require setting the logging level to com.sun.javafx.scene.control.skin.VirtualFlow such that no log messages are written.

      This introduces unnecessary coupling between an application and the logging framework, and requires more effort on behalf of developers, should they even know that this issue is lurking.

            aroy Abhijit Roy (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: