mscharhag, Programming and Stuff;

A blog about programming and software development topics, mostly focused on Java technologies including Java EE, Spring and Grails.

Posts tagged with Code Quality

  • Tuesday, 15 September, 2020

    Implementing the Proxy Pattern in Java

    The Proxy Pattern

    Proxy is a common software design pattern. Wikipedia does a good job describing it like this:

    [..] In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. [..]

    (Wikipedia)

    UML class diagram:

    proxy pattern

    A client requires a Subject (typically an interface). This subject is implemented by a real implementation (here: RealSubject). A proxy implements the same interface and delegates operations to the real subject while adding its own functionality.

    In the next sections we will see how this pattern can be implemented in Java.

    Creating a simple proxy

    We start with an interface UserProvider (the Subject in the above diagram):

    public interface UserProvider {
        User getUser(int id);
    }

    This interface is implemented by UserProviderImpl (the real implementation):

    public class UserProviderImpl implements UserProvider {
        @Override
        public User getUser(int id) {
            return ...
        }
    }

    UserProvider is used by UsefulService (the client):

    public class UsefulService {
        private final UserProvider userProvider;
    
        public UsefulService(UserProvider userProvider) {
            this.userProvider = userProvider;
        }
        
        // useful methods
    }

    To initialize a UsefulService instance we just have to pass a UserProvider object to the constructor:

    UserProvider userProvider = new DatabaseUserProvider();
    UsefulService service = new UsefulService(userProvider);
    
    // use service

    Now let's add a Proxy object for UserProvider that does some simple logging:

    public class LoggingUserProviderProxy implements UserProvider {
        private final UserProvider userProvider;
    
        public LoggingUserProviderProxy(UserProvider userProvider) {
            this.userProvider = userProvider;
        }
    
        @Override
        public User getUser(int id) {
            System.out.println("Retrieving user with id " + id);
            return userProvider.getUser(id);
        }
    }

    We want to create a proxy for UserProvider, so our proxy needs to implement UserProvider. Within the constructor we accept the real UserProvider implementation. In the getUser(..) method we first write a message to standard out before we delegate the method call to the real implementation.

    To use our Proxy we have to update our initialization code:

    UserProvider userProvider = new UserProviderImpl();
    LoggingUserProviderProxy loggingProxy = new LoggingUserProviderProxy(userProvider);
    UsefulService usefulService = new UsefulService(loggingProxy);
    
    // use service

    Now, whenever UsefulService uses the getUser() method we will see a console message before a User object is returned from UserProviderImpl. With the Proxy pattern we were able to add logging without modifying the client (UsefulService) and the real implementation (UserProviderImpl).

    The problem with manual proxy creation

    The previous solution has a major downside: Our Proxy implementation is bound to the UserProvider interfaces and therefore hard to reuse.

    Proxy logic is often quite generic. Typical use-cases for proxies include caching, access to remote objects or lazy loading.

    However, a proxy needs to implement a specific interface (and its methods). This contradicts with re-usability.

    Solution: JDK Dynamic Proxies

    The JDK provides a standard solution to this problem, called Dynamic Proxies. Dynamic Proxies let us create a implementation for a specific interface at runtime. Method calls on this generated proxy are delegated to an InvocationHandler.

    With Dynamic Proxies the proxy creation looks like this:

    UserProvider userProvider = new DatabaseUserProvider();
    UserProvider proxy = (UserProvider) Proxy.newProxyInstance(
            UserProvider.class.getClassLoader(),
            new Class[]{ UserProvider.class },
            new LoggingInvocationHandler(userProvider)
    );
    UsefulService usefulService = new UsefulService(proxy);

    With Proxy.newProxyInstance(..) we create a new proxy object. This method takes three arguments:

    • The classloader that should be used
    • A list of interfaces that the proxy should implement (here UserProvider)
    • A InvocationHandler implementation

    InvocationHandler is an interface with a single method: invoke(..). This method is called whenever a method on the proxy object is called.

    Our simple LoggingInvocationHandler looks like this:

    public class LoggingInvocationHandler implements InvocationHandler {
    
        private final Object invocationTarget;
    
        public LoggingInvocationHandler(Object invocationTarget) {
            this.invocationTarget = invocationTarget;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(String.format("Calling method %s with args: %s",
                    method.getName(), Arrays.toString(args)));
            return method.invoke(invocationTarget, args);
        }
    }

    The invoke(..) method has three parameters:

    • The proxy object on which a method has been called
    • The method that has been called
    • A list of arguments that has been passed to the called method

    We first log the method and the arguments to stdout. Next we delegate the method call to the object that has been passed in the constructor (note we passed the real implementation in the previous snippet).

    The separation of proxy creation (and interface implementation) and proxy logic (via InvocationHandler) supports re-usability. Note we do not have any dependency to the UserProvider interface in our InvocationHandler implementation. In the constructor we accept a generic Object. This gives us the option to reuse the InvocationHandler implementation for different interfaces.

    Limitations of Dynamic Proxies

    Dynamic Proxies always require an interface. We cannot create proxies based on (abstract) classes.

    If this really a great issue for you can look into the byte code manipulation library cglib. cglib is able to create proxy via subclassing and therefore is able to create proxies for classes without requiring an interface.

    Conclusion

    The Proxy Pattern can be quite powerful. It allows us to add functionality without modifying the real implementation or the client.

    Proxies are often used to add some generic functionality to existing classes. Examples include caching, access to remote objects, transaction management or lazy loading.

    With Dynamic Proxies we can separate proxy creation from proxy implementation. Proxy method calls are delegated to an InvocationHandler which can be re-used.

    Note that in some situations the Proxy Pattern can be quite similar to the Decorator pattern (see this Stackoverflow discussion).

     

  • Saturday, 1 February, 2020

    Validating code and architecture constraints with ArchUnit

    Introduction

    ArchUnit is a library for checking Java code against a set of self defined code and architecture constraints. These constraints can be defined in a fluent Java API within unit tests. ArchUnit can be used to validate dependencies between classes or layers, to check for cyclic dependencies and much more. In this post we will create some example rules to see how we can benefit from ArchUnit.

    Required dependency

    To use ArchUnit we need to add the following dependency to our project:

    <dependency>
    	<groupId>com.tngtech.archunit</groupId>
    	<artifactId>archunit-junit5</artifactId>
    	<version>0.13.0</version>
    	<scope>test</scope>
    </dependency>

    If you are still using JUnit 4 you should use the archunit-junit4 artifact instead.

    Creating the first ArchUnit rule

    Now we can start creating our first ArchUnit rule. For this we create a new class in our test folder:

    @RunWith(ArchUnitRunner.class) //only for JUnit 4, not needed with JUnit 5
    @AnalyzeClasses(packages = "com.mscharhag.archunit")
    public class ArchUnitTest {
    
        // verify that classes whose name name ends with "Service" should be located in a "service" package
        @ArchTest
        private final ArchRule services_are_located_in_service_package = classes()
                .that().haveSimpleNameEndingWith("Service")
                .should().resideInAPackage("..service");
    }

    With @AnalyzeClasses we tell ArchUnit which Java packages should be analyzed. If you are using JUnit 4 you also need to add the ArchUnit JUnit runner.

    Inside the class we create a field and annotate it with @ArchTest. This is our first test.

    We can define the constraint we want to validate by using ArchUnits fluent Java API. In this example we want to validate that all classes whose name ends with Service (e.g. UserService) are located in a package named service (e.g. foo.bar.service).

    Most ArchUnit rules start with a selector that indicates what type of code units should be validated (classes, methods, fields, etc.). Here, we use the static method classes() to select classes. We restrict the selection to a subset of classes using the that() method (here we only select classes whose name ends with Service). With the should() method we define the constraint that should be matched against the selected classes (here: the classes should reside in a service package).

    When running this test class all tests annotated with @ArchTest will be executed. The test will fail, if ArchUnits detects service classes outside a service package.

    More examples

    Let's look at some more examples.

    We can use ArchUnit to make sure that all Logger fields are private, static and final:

    // verify that logger fields are private, static and final
    @ArchTest
    private final ArchRule loggers_should_be_private_static_final = fields()
            .that().haveRawType(Logger.class)
            .should().bePrivate()
            .andShould().beStatic()
            .andShould().beFinal();
    

    Here we select fields of type Logger and define multiple constraints in one rule.

    Or we can make sure that methods in utility classes have to be static:

    // methods in classes whose name ends with "Util" should be static
    @ArchTest
    static final ArchRule utility_methods_should_be_static = methods()
            .that().areDeclaredInClassesThat().haveSimpleNameEndingWith("Util")
            .should().beStatic();

    To enforce that packages named impl contain no interfaces we can use the following rule:

    // verify that interfaces are not located in implementation packages
    @ArchTest
    static final ArchRule interfaces_should_not_be_placed_in_impl_packages = noClasses()
            .that().resideInAPackage("..impl..")
            .should().beInterfaces();

    Note that we use noClasses() instead of classes() to negate the should constraint.

    (Personally I think this rule would be much easier to read if we could define the rule as interfaces().should().notResideInAPackage("..impl.."). Unfortunately ArchUnit provides no interfaces() method)

    Or maybe we are using the Java Persistence API and want to make sure that EntityManager is only used in repository classes:

    @ArchTest
    static final ArchRule only_repositories_should_use_entityManager = noClasses()
            .that().resideOutsideOfPackage("..repository")
            .should().dependOnClassesThat().areAssignableTo(EntityManager.class);

    Layered architecture example

    ArchUnit also comes with some utilities to validate specific architecture styles.

    For example can we use layeredArchitecture() to validate access rules for layers in a layered architecture:

    @ArchTest
    static final ArchRule layer_dependencies_are_respected = layeredArchitecture()
            .layer("Controllers").definedBy("com.mscharhag.archunit.layers.controller..")
            .layer("Services").definedBy("com.mscharhag.archunit.layers.service..")
            .layer("Repositories").definedBy("com.mscharhag.archunit.layers.repository..")
            .whereLayer("Controllers").mayNotBeAccessedByAnyLayer()
            .whereLayer("Services").mayOnlyBeAccessedByLayers("Controllers")
            .whereLayer("Repositories").mayOnlyBeAccessedByLayers("Services");

    Here we define three layers: Controllers, Services and Repositories. The repository layer may only accessed by the service layer while the service layer may only be accessed by controllers.

    Shortcuts for common rules

    To avoid that we have to define all rules our self, ArchUnit comes with a set of common rules defined as static constants. If these rules fit our needs, we can simply assign them to @ArchTest fields in our test.

    For example we can use the predefined NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS rule if we make sure no exceptions of type Exception and RuntimeException are thrown:

    @ArchTest
    private final ArchRule no_generic_exceptions = NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;

    Summary

    ArchUnit is a powerful tool to validate a code base against a set of self defined rules. Some of the examples we have seen are also reported by common static code analysis tools like FindBugs or SonarQube. However, these tools are typically harder to extend with your own project specific rules and this is where ArchUnit comes in.

    As always you can find the Sources from the examples on GitHub. If you are interested in ArchUnit you should also check the comprehensive user guide.

  • Monday, 23 February, 2015

    Static code analysis with JArchitect

    A few months ago Dane from JArchitect team was nice enough to offer me a free JArchitect 4 Pro license. Over the last days I finally managed to look into JArchitect.

    JArchitect is a quite powerful static code analyser for JVM languages (besides Java it also supports Scala, Groovy and others). It is available for Windows, Linux and Mac OS X. In this post I want to show you some of JArchitect's features.

    Getting started with JArchitect

    As an example I analysed the popular Java Library JUnit using JArchitect. The Screenshots you in this post are all taken from the JUnit analysis result.

    Importing JUnit into JArchitect was actually quite simple. Note that JArchitect analyses the compiled byte code, source files are not required. So I cloned the JUnit repository and called mvn compile. After that, all I had to do was adding JUnit's pom.xml to a new JArchitect project.

    After pressing the Run Analysis button JArchitect summarizes common metrics on a dashboard screen:
     

    JArchitect Dashboard


    Here we can see the lines of code, method complexity, comment rate and various other values. This summary is followed by a couple of trend charts that show how these values changed over time.

    JArchitect trend chart

    Of course you can also configure your own charts, if you want to see trends of different values.

    Analyzing dependencies

    Next we will look at the third party dependencies of JUnit. JArchitect provides a nice interactive graph for this.

    JArchitect dependency graph (1)
     

    Since JUnit only depends on the Java Runtime (rt) and Hamcrest this graph does not have much to show. I am sure you can imagine that this could be much more complex for a larger project.

    Looking at JUnits package dependencies is a bit more interesting. The following Screen shows a section of JUnits package dependency graph.

     

    JArchitect dependency graph (2)

     


    I selected the junit.framework package to see how this package relates to other packages. The different colored arrows show which packages use junit.framework (green), which other packages are used by junit.framework (blue) and mutually dependent packages (red).

    The dependency matrix is another way to look at project dependencies:

     

    JArchitect dependency matrix (1)


    This matrix style view shows you exactly the dependencies between different components (packages, classes or methods). Here I selected the blue field with the number 10 (where the orange lines cross). This shows that the junit.framework package uses 10 members of the java.lang.reflect package (the dependency direction is shown by the white arrow at the selected field).

    We can dig deeper, and look at this at class and method level.

     

    JArchitect dependency matrix(2)


    So it looks like the class junit.framework.TestCase makes use of the method java.lang.Class.getName().

    Tree maps

    Tree map charts are another way to look into a project with JArchitect. The following chart shows the number of code lines in JUnit packages, classes and methods.

     

    JArchitect metrics

     

    In this example chart we cannot see any overly large rectangle, which is a good sign. This probably means that complex parts are well divided into multiple classes and packages (no god object is present).

    JArchitect can generate such tree maps for lines of code, cyclomatic complexity, number of variables and various other metrics.

    Code queries

    To extract various metrics out of a project, JArchitect uses a custom query language call Code Query Linq (CQLinq). As the name suggests this is a query language based on LINQ.

     

    JArchitect queries

     

    This image shows the query of JArchitect's Methods with too many parameters rule. It looks for methods with more than 8 parameters and creates a warning if one or more methods are found.

    You can see (and change) all the standard queries provided by JArchitect. Code queries are actually a very cool feature. You can easily create your own queries to extract project specific data you are interested in. 

    Quick summary

    JArchitect is a powerful tool for static code analysis. It can provide a lot of insight into complex code bases. Using custom code queries you are able to build your own rule sets in a very comfortable way.

    In this example I used the JArchitect user interface (VisualJArchitect) for running the code analysis and viewing the results. It is also possible to integrate JArchitect directly into your build process (using a Maven plugin or command line tools). This way you are able to automatically create reports in HTML format.