2014-09-20

Homework For Tim Cook

After many frustrating hours wasted on many interactions with Apple for submitting an iOS app to the App Store, I have this wish:

Lock Tim Cook in a room alone with nothing but:


  • A cup of coffee.
  • A MacBook running:
    • Xcode with a completely built iOS app.
    • Safari with a pair of windows for:
      • The iTunesConnect site.
      • The developer.apple.com site. 
  • A relief bucket.


Do not let him leave the room until the app has been successfully submitted to the App Store.

2014-08-06

Postgres User For App

Installing Postgres means creating a new operating-system (Unix) user, by default named "postgres".

At the same time a superuser is created within the Postgres environment by the same name. This superuser can do anything, including dropping a table and even deleting an entire database (catalog).

Postgres experts commonly suggest that you create a new user with most but not all of the powers of the superuser. Creation and deletion of databases should be omitted. This is the basic administrator user that you use typically use in day-to-day work. This admin user is what you usually use as the login user in pgAdmin or your other admin tools.

When developing an app, the data-access layer will need to connect to the Postgres database as a user. Again, experts commonly suggest you create a Postgres user for this purpose. The app-user normally should not have the power to create or delete tables, as well as schema and databases. Even some individual tables may be read-only for this user, without powers to insert, update, or delete.

You may even want to create multiple app-users, each with different powers depending on what parts of the app will be engaged by the human user. For example, bookkeepers may have read-write access to tables that salespeople do not. You can enforce this access at the database engine (Postgres) as well as at your app (ex: Java & Vaadin).

Your app may be calling functions, such as the UUID-OSSP library. Those functions are protected, and you must grant permission to those as well.
For a basic app, the app-user might have CRUD access to all the tables and the functions. Here is the SQL code you must run after adding a table or function to grant powers to your app user. The code assumes you used the default schema named public, so modify as needed.

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO acme_app_;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO acme_app_;

2014-07-15

NetBeans Debugger – Show Value as 'toString'

NetBeans 8 (and earlier) has an important debugging feature hidden away: Show a variable’s value as rendered by its own toString method.

You can expose an additional column for this value in the debugger’s Variables pane. Notice the orange splotch icon tucked away by itself in the upper-right corner. Click that icon to present a Change Visible Columns dialog. Check the checkbox labeled String Value: String representation of the value.

Of course this feature requires safe-and-sane implementations of toString method on exposed objects. The risk of misbehaved implementations is presumably the reason this column is not exposed by default.

Screen shot of "Change Visible Columns" dialog box

2014-07-10

Example Use of Java Try-With-Resource For JDBC

Here is a nice nugget of example code for how to use a JDBC PreparedStatement with the try-with-resource feature in Java. This feature automatically closes resources even if any exceptions are thrown.

Note how for a PreparedStatement we must nest one try-with-resource inside another. Apparently an exception thrown by the inner one will be caught by the outer one.

This example is taken from this answer in StackOverflow. I am posting here for my copy-paste convenience.

public List<User> getUser(int userId) {
    String sql = "SELECT id, username FROM users WHERE id = ?";
    List<User> users = new ArrayList<>();
    try (Connection con = DriverManager.getConnection(myConnectionURL);
         PreparedStatement ps = con.prepareStatement(sql);) {
        ps.setInt(1, userId);
        try (ResultSet rs = ps.executeQuery();) {
            while(rs.next()) {
                users.add(new User(rs.getInt("id"), rs.getString("name")));
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return users;
}


Trailing Semicolon

And speaking of copy-paste, I can also share a small but important fact: Note the trailing semicolon on the second line of the outer "try". Two statements within the try, each terminated by a semicolon. Early drafts of this feature forbade the trailing semicolon and many folks mistakenly believe that is still the case. But in the final release the Java team realized the convenience of copy-pasting lines without having to remember to remove (or add) the trailing semicolon statement terminator. I suggest always including that optional semicolon.

2014-04-08

Quick Start to Logging with SLF4J and Logback for a Maven-based Project

I followed this informative but slightly out -of-date article, How to setup SLF4J and LOGBack in a web app - fast, to get started with logging in my Vaadin web app. Here is my description of the same steps using NetBeans 8 with Java 8 hooked up to Tomcat 8 on a Mac mini running Mavericks.

First create your Maven-based project. In my case, I'm using version 1.1.1 of the Vaadin Plugin for NetBeans  to create a new Vaadin 7.1 project.

Add the logging façade library, SLF4J.
  1. In the NetBeans project navigator pane, context-click on the Dependencies item.
  2. Choose Add Dependency.
  3. Type: slf4j-api
  4. Open the org.slf4j : slf4j-api item to choose the latest version.
I find that repository listing in NetBeans is consistently inconsistent, in other words, psycho-crazy. Close that dialog, repeat the same steps,  and get a different list of version numbers. Sometimes you see later versions, sometimes you see only earlier versions. So check the web site for the desired dependency (SLF4J in this case) to determine the true latest version. Repeat that dialog a few times until it randomly decides to show you a version number close to the true latest. Choose that item. Later you can edit your "pom.xml" to the true latest.

In a fashion similar to SLF4J, let's add Logback. Logback is a direct implementation of that SLF4J façade. You can use nearly any other Java-based logging frameworks in conjunction with an adapter. Logback needs no adapter. Logback is the successor to Log4J, both of which were created by the same man.

We need two jars for LogBack, "classic" and "core". However, adding a dependency for "classic" will automatically get us "core".
  1. In the NetBeans project navigator pane, context-click on the Dependencies item.
  2. Choose Add Dependency.
  3. Type: logback-classic
  4. Open the ch.qos.logback : logback-classic item.
  5. Choose the latest version offered.
Again, you'll probably get a not-quite-right list of versions. Take the latest offered, and update later.

Save all your files, and do a clean-and-build of your project (Hammer & Broom icon) to get Maven to do its duty. You should find in the project navigator pane a new item Other Sources. Expand that item to find a src/main/resources item.
  1. Context-click the src/main/resources item to create a new XML file.
  2. Name the new XML file: logback.xml
  3. Into that file, past the following XML text seen below.
  4. Change the XML text, replacing "com.example" with your own project’s top package.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <logger name="com.example" level="TRACE"/>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
   
</configuration>


This XML is different than that older article, having replaced the deprecated layout with an encoder. This XML configures Logback to send your logging messages to the NetBeans console. You'll need to make alterations for use when deployed to production, but this should get you started in development.

Now try it out. In your Vaadin app, locate the MyVaadinUI.java file that drives your app.
  1. Add an import: import org.slf4j.*;
  2. At the top of your class definition, add the line:
    static final Logger LOG = LoggerFactory.getLogger(MyVaadinUI.class);
  3. In the init method of this class, add the following code to see if logging works.
        LOG.trace("Yogi - Logging Test - Trace");
        LOG.debug("Yogi - Logging Test - Debug");
        LOG.info("Yogi - Logging Test - Info");
        LOG.warn("Yogi - Logging Test - Warn");
        LOG.error("Yogi - Logging Test - Error");

      
Run your Vaadin app. You may need to do a clean-and-build (Hammer & Broom icon). On one of the tabs in the NetBeans "Output" console pane you should see your messages.

To update the version numbers of SLF4J and Logback, look in the NetBeans project navigator pane. Expand the Project Files item to locate and open "pom.xml" file. Search for "slf4j" and "logback" and update each one’s version tag with the number you know to be current. Saving the XML file may cause Maven to do its duty. If not, try a clean-and-build.

Caveat: I am a Maven and SLF4J and Logback triple newbie. The above steps worked for me, but I cannot say that I understand them fully. Follow these steps at your own risk. Backup your project first.

2014-02-02

Simple Vaadin Charts Example

While watching this video demo, on this Vaadin blog post, about the new Vaadin plugin 1.1.x for NetBeans 7 IDE, I noticed this very simple example being done with Vaadin Charts 1.1.x. Just 3 lines of code.

Vaadin Charts can be a bit overwhelming to approach because of its huge power and flexibility. So I was glad to see, and try, this little "Hello World" example.

NOTE: Vaadin Charts is a commercial product, requiring a paid license. A 30-day free trial is available.

Code…

// Chart
Chart chart = new Chart();
chart.getConfiguration().addSeries( new ListSeries( 1, 2, 3 ) );
layout.addComponent( chart );

You can simply add that code to the default app created by the Vaadin Plugin, and run.

See this YouTube video for another demo of Vaadin Charts, from their webinar.