Skip to content

Code missing closing parenthesis. Errant continue statement. #267

Description

@authentictech

In Learn > The Java I/O API > File System Basics > Managing File Attributes, section "Determining MIME Type", there is a missing closing parenthesis:

try {
    String type = Files.probeContentType(filename);
    if (type == null) {
        System.err.format("'%s' has an" + " unknown filetype.%n", filename);
    } else if (!type.equals("text/plain") { // <-- parenthesis missing here
        System.err.format("'%s' is not" + " a plain text file.%n", filename);
        continue;
    }
} catch (IOException x) {
    System.err.println(x);
}

I also get a compiler error about the continue statement: "error: continue outside of loop". (I presume the code was copied originally from a loop.)

Activity

  1. willy-b commented on Aug 4, 2026

    @willy-b

    Great catch!

    Re: why they have a "continue" there -- it looks possibly copied from the more complete looping code example they provided later in the tutorial at https://dev.java/learn/java-io/file-system/watching-dir-changes/#processing-events (archived as is at https://web.archive.org/web/20260710052409/https://dev.java/learn/java-io/file-system/watching-dir-changes/#processing-events )

    [... run the setup in earlier paragraphs by the dev.java team, to obtain `watcher` and register a directory with the watcher...]
    // wait for key to be signaled
    WatchKey key;
    try {
      key = watcher.take();
    } catch (InterruptedException x) {
      return; // [not valid in JShell but would be valid in an enclosing method]
    }
    // [...]
    for (WatchEvent<?> event: key.pollEvents()) {
            WatchEvent.Kind<?> kind = event.kind();
    
            // This key is registered only
            // for ENTRY_CREATE events,
            // but an OVERFLOW event can
            // occur regardless if events
            // are lost or discarded.
            if (kind == OVERFLOW) {
                continue;
            }
    
            // The filename is the
            // context of the event.
            WatchEvent<Path> ev = (WatchEvent<Path>)event;
            Path filename = ev.context();
    
            // Verify that the new
            //  file is a text file.
            try {
                // Resolve the filename against the directory.
                // If the filename is "test" and the directory is "foo",
                // the resolved name is "test/foo".
                Path child = dir.resolve(filename);
                if (!Files.probeContentType(child).equals("text/plain")) { // [btw this is unsafe for NPEs: this should be `if (!"text/plain".equals(Files.probeContentType(child)))` to avoid a NPE]
                    System.err.format("New file '%s'" +
                        " is not a plain text file.%n", filename);
                    continue;
                }
            } catch (IOException x) {
                System.err.println(x);
                continue;
            }
    
            // Email the file to the
            //  specified email alias.
            System.out.format("Emailing file %s%n", filename);
            //Details left to reader....
    }
    // [...]
    

    I agree without the context of their later example it is confusing and that the continue should probably not be shown in the simplified pseudocode shown on https://dev.java/learn/java-io/file-system/metadata/#mime-type .

    BTW, on the other page this example appears copied from https://web.archive.org/web/20260710052409/https://dev.java/learn/java-io/file-system/watching-dir-changes/#processing-events (archived as is at https://web.archive.org/web/20260710052409/https://dev.java/learn/java-io/file-system/watching-dir-changes/#processing-events )


    Also, just noting as I reported some errors on these pages earlier that
    the particular code example you are reporting here on https://dev.java/learn/java-io/file-system/metadata/#mime-type was NOT updated by me NOR the dev.java team as part of recommendations I made in a ticket on that series of articles ( #210 (comment) ) or otherwise, though it sounds similar to material discussed there and occurs close to items I reported bugs in within that ticket.

    The error you report here was present from at least 2025 already: https://web.archive.org/web/20251012140905/https://dev.java/learn/java-io/file-system/metadata/ .


    Thanks!

  2. JosePaumard commented on Aug 5, 2026

    @JosePaumard
    Contributor

    Thanks to both of your for this report! A fix is on its way.
    As for the comment #210, I see that you closed it, does your comment on this one mean that there are in fact elements that should be fixed and that were not?
    Thank you again!

  3. willy-b commented on Aug 22, 2026

    @willy-b

    Hey, I don't see that your fix, @JosePaumard is live for what was reported by @authentictech above on https://dev.java/learn/java-io/file-system/metadata/ (archived as is still with the missing parenthesis at https://megalodon.jp/2026-0823-0713-08/https://dev.java:443/learn/java-io/file-system/metadata/ ; had to switch from web.archive.org to megalodon.jp as web.archive.org is having trouble making snapshots of dev.java right now; note you must check the code in the HTML as the snippets don't render on megalodon.jp but the code is saved).

    I do see that you made the change for the bug in the upstream code I reported in this ticket re: https://dev.java/learn/java-io/file-system/watching-dir-changes/#processing-events (the example the fragment @authentictech was referring to seems derived from, why it had a continue), as that code appears updated by you to be NPE safe (on the left in the image below vs right hand side on web.archive.org):

    Image

    (archived as is at https://megalodon.jp/2026-0823-0711-41/https://dev.java:443/learn/java-io/file-system/watching-dir-changes/ (noting you must search the <snippet> in the HTML as megalodon doesn't show snippets visibly but still archives them correctly) , compare to an earlier snapshot at https://web.archive.org/web/20260706222340/https://dev.java/learn/java-io/file-system/watching-dir-changes/ )


    @JosePaumard , the other ticket, #210 , got too large (I was reporting content bugs to the dev.java team on this series of articles for 4 months straight, if you check the ticket, so wanted you to get some credit for your fixes especially as I had to slow down for a bit), and I didn't have any additional known bugs in hand to report for it, so
    that issue which had been opened by stating

    Just opening an issue to report some typos and small issues I found in the "File System Basics" articles of the "The Java I/O API" tutorial ( https://dev.java/learn/java-io/file-system/ ).

    was closed with the following comment in #210 (comment) :

    The items reported above were either resolved (or you acknowledged them as "Won't Fix"), so I am marking this closed.

    (also you had just mentioned in the preceding some of the work on that ticket was duplicative with other open tickets, so wanted to reduce the number of open tickets)


    I believe @authentictech is filing 1 issue/ticket per typo/broken example from the dev.java team, rather than reporting large batches of errors/bugs per issue/ticket like I have been trying to (different style, no judgment from me).

    E.g. @authentictech 's other #256 (comment) or #251 (comment) each report an item for a single paragraph or code example within the Streams tutorial (and were closed) while I have continued to report issues in #200 on the Streams tutorial overall (probably a good time to close that and open a new one for any additional issues, for example, though I had not closed it as I kept incidentally finding more items every time I reviewed to confirm the ones reported had been fixed).

    If you prefer 1 issue per typo/bug I can file like that, which has the advantage that a single thing is denoted fixed when the issue is closed rather than a list of things. But I fear it may lead to too many issues as I normally report several typos / bugs per comment on some of these issues. Instead of opening an additional issue for example to point out the code @authentictech is discussing appears derived from a later example which also has related errors (which he did not report here), I just added it to this issue here in #267 (comment) for example.

    In the issue @JosePaumard is asking me about, if I filed like @authentictech then just the two following comments from that issue would be several issues each:
    #210 (comment)
    or
    #210 (comment)

    rather than just a couple of comments on that one issue. Let me know if you have a preference for smaller or larger issues or some other recommended approach.

    Also for typos, no pressure but I did add several more to the open typo ticket I have at #263 a couple of weeks ago. I am not aware of any more typos on the site (I am scanning, not making changes) so will close that once the remaining ones listed are fixed.

    Thanks again to the dev.java team and to @authentictech for joining me in reporting bugs on these articles and finding some more that I had not yet uncovered.

  4. authentictech commented on Aug 24, 2026

    @authentictech
    Author

    @willy-b I actually favour 1 issue per tutorial page rather than 1 issue per error/bug but it may seem like 1 issue per error/bug if I only find one per page - otherwise I'll add it as a comment. :-) Perhaps this is a happy medium? it just feels more "modular" to me and easier to manage from the other end. I'm also working my way through the tutorials scholastically rather than looking for mistakes so I am probably missing lots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions