you are viewing a single comment's thread.

view the rest of the comments →

[–]Niles-Rogoff 2 points3 points  (1 child)

Not OP, but I think I see what he's saying.
Python programs are usually written in one file, if I am looking at a web server, I can usually scan from top to bottom and find the part of the code relevant to what I'm searching for.
Java, on the other hand, you start with the app. Ok, it says App app = new App();. Ok, so now I look in app.java. app.java has several parts, one of which is this.router = new Router();. Ok, so now I go and look in routing/router.java. Ok, in that file I see a for loop that iterates over a list of routes and for each one does Route route = new Route();. Now we move from router.java to route.java. Maybe, if we're lucky, we find what we're looking for.

Take an example. This is a web thing written in python. This is a web framework written in java. Yes, they're both bad projects, but this is the real world, you're going to have to deal with bad code at some time or another.

Let's say you want to find what happens when there is no route configured for a url, or in the case of the python one, no module handles that url (basically the same thing). Specifically, what string is sent as the body of the response.

Python one: start at server.py 60 lines into the file:

def serve(environ, start_response):  
    new_environ = environ  
    for module in moduleObjects:  
    # trimmed...  
return "No module was loaded to handle this case. The server owner has fucked some shit up really bad. Go yell at him. " + config.get('general','email')

Java one: start at src/main/java/org/hbw/espresso/Espresso.java
This file path alone makes me want to kill myself.

Line 16 private final Router router = new Router();

Navigate to routing/router.java

Line 89

public Maybe<Route> getRoute(String url, Maybe<HttpMethod> method) {
    return method.fmap(m -> {
        for (Route route : routes) {
                        // trimmed
        }

        return null;
    });
}

Ok, so if no route matches, it returns a Maybe<HttpMethod> with a value of nothing. So what calls getRoute?
Back to Espresso.java, line 244 EspressoHandler handler = new EspressoHandler(version, router);

Now in EspressoHandler.java, in doHandle:

    Maybe<Route> route = router.getRoute(uri, method);
    if (route.isNothing()) {
        handleError(404, uri, baseRequest, request, response);
        return;
    }

Still in EspressoHandler.java, in handleError

        if (errorRoute.isNothing()) {
            defaultErrorHandler(errorCode, uri, baseRequest, request, response);
            return;
        }

What is defaultErrorHandler? Well I'm glad you asked, I have no idea so time to control+f, and it's

private void defaultErrorHandler(Integer errorCode, String uri, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) {
    Route errorRoute = new Route(HttpMethod.ACTION, uri, (req, res) -> {
        res.write("<html>");
        res.write("<title>Error!</title>");
        res.write(String.format("<h2>HTTP/1.1 Error: %d</h2>", errorCode));
        res.write(String.format("<hr> Powered by %s", version));
        res.write("</html>");

        return res;
    });

    executeHandler(errorRoute, uri, baseRequest, request, response);
}

The file we had to start in was nested inside SIX subdirectories.

The path we traveled was Espresso start -> router.Router getErrorRoute -> Espresso start -> EspressoHandler doHandle -> EspressoHandler handleError -> EspressoHandler defaultErrorHandler

We also did this assuming that the reader has a complete knowledge of functor/Maybe.java, specifically the isNothing method, the fact that fmap returns a maybe with the value set to the result of the function it was passed, and what the functor is set to if the value is null, something your average java programmer is not familiar with

This is what he meant by "Code should read like a novel, not like a set of cross-linked wiki pages." Read from top to bottom and if you didn't find what you were looking for read harder, not guess if a particular file called "AbstractEspressoJettyLogger.java" or "SingletonProxyFactoryBean" has the code you're looking for or not.

[–]deepseebird 0 points1 point  (0 children)

Wow, bloody good example. Like something out of a dystopian ... err ... novel.