Querying Active Users on Active Directory

Here’s how to query non-disabled users on Active Directory. There are 2 conditions I want to set:

1. Object is of type user / person

(objectCategory=person)

2. User is active, not disabled
This is a tricky one, luckily there’s a way to use bitwise filter to find not-disabled users. The flag for disabled account in AD is 0x02 (decimal 2), hence we can create a negative condition which reverse this condition:

(!UserAccountControl:1.2.840.113556.1.4.803:=2)

The odd 1.2.840.113556.1.4.803 portion there is actually a bitwise OR operation (thanks Microsoft for making it so subtle)

So combining both condition together with (& operator here’s my final query

(&(!UserAccountControl:1.2.840.113556.1.4.803:=2)(objectCategory=person))
active directory

Permanently Adding IP Route To Mac OSX VPN Connection

I’m annoyed, each time I connect to my office VPN I have to manually add an IP route so certain IP group is resolvable. Here’s how you can make the change permanent:

Add the route command to /etc/ppp/ip-up. This file gets executed each time VPN connection is activated.

#File: /etc/ppp/ip-up
#!/bin/sh
/sbin/route add 192.168.16.0/24 $5

In the above configuration I routed any IP starting with 192.168.16 to the newly established VPN connection (denoted by $5 variable).

You can check your IP routing table by using netstat -rn

Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default                 UGSc           36        0    ppp0
default            192.168.1.1        UGScI          14        0     en0
25                 link#8             UC              1        0    ham0
25.84.162.40       7a:79:19:51:a5:3c  UHLWIi          1        1     lo0
127                127.0.0.1          UCS             0        0     lo0
127.0.0.1          127.0.0.1          UH              1   143939     lo0
169.254            link#4             UCS             0        0     en0
192.168.1          link#4             UCS             4        0     en0
192.168.1.1        0:60:64:91:be:65   UHLWIir        18      618     en0   1183
192.168.1.2        127.0.0.1          UHS             0        0     lo0
192.168.1.5        0:23:ae:a:c9:63    UHLWI           0       21     en0   1016
192.168.1.8        1c:1a:c0:6f:b7:6a  UHLWI           0        0     en0   1139
192.168.1.9        1c:1a:c0:6f:b7:6b  UHLWI           0        0     en0   1140
192.168.16              UGSc            1        0    ppp0
192.168.18         ppp0               USc             0        0    ppp0
          UHr            40       16    ppp0
     192.168.1.1        UGHS            1      376     en0

RESTful Web Service With Spring Data Rest and Spring Security

Source code of this article is available on github:

This article is written against following versions

  • Spring 4.1.4.RELEASE
  • Spring Boot 1.2.1.RELEASE
  • Spring Security 3.2.5.RELEASE

Table of Content

Spring Security comes handy when you need to secure your RESTful web service. Let’s give this a go! In this example I’ll create a REST service exposing a Cat entity. It simply have name and colour field

{
  "name" : "Tom",
  "colour" : "Black"
};

Creating the Service

Setup a new maven project with following pom.xml. We’ll leverage Spring Boot to simplify the work.


  4.0.0
  
  
    org.springframework.boot
    spring-boot-starter-parent
    1.2.1.RELEASE
  
  
  com.gerrydevstory.rest1
  rest1
  0.0.1-SNAPSHOT
  war
  
  
    
      org.springframework.boot
      spring-boot-starter-web
    
    
      org.springframework.boot
      spring-boot-starter-data-jpa
    
    
      org.springframework.boot
      spring-boot-starter-data-rest
    
    
      org.hsqldb
      hsqldb
      runtime
    
  
  
  
    
      
        org.springframework.boot
        spring-boot-maven-plugin
      
      
        org.apache.maven.plugins
        maven-compiler-plugin
        
          7
          7
        
      
    
  

Setup a main configuration class. This substitutes the old-fashioned spring context xml. Spring Boot will do a lot of under-the-hood work to setup various bits and pieces using auto configuration

guration

public class Application {

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
  
}

Now let’s create our Cat JPA entity


public class Cat {

  @Id
  
  private long id;
  
  private String name = "";
  
  private String colour = "";

  /* .. getters & setters omitted .. */
}

Since we included dependency to spring-boot-starter-data-jpa, Spring Boot will automatically set us up with JPA with Hibernate implementation. Also note that on pom.xml we declared a dependency to hsqldb which will automatically give us datasource to an embedded HSQL database.

Next, let’s create a Spring Data repository for Cat.

esource
public interface CatRepository extends PagingAndSortingRepository {

}

Again, spring-boot-starter-data-jpa will auto setup spring-data-jpa for me, and it will automatically provide an implementation of the repository interface at runtime.

Take a note at the esource annotation. This annotation tells Spring Data REST to expose the repository as REST service as well.

Testing the Service

Now you’re ready to run the app using the embedded tomcat container. Run following maven command

mvn clean test spring-boot:run

Your app will start at http://localhost:8080

Let’s try some cats operation using curl (Windows version of curl is available at http://curl.haxx.se/download.html)

Get all cats:

$ curl http://localhost:8080/cats
{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/cats{?page,size,sort}",
      "templated" : true
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

-i option will display HTTP response headers.

There’s nothing there since we haven’t added any cat.

Now let’s try add a cat named “Tom” with colour “black”:

$ curl -i -X POST -d '{"name" : "Tom", "colour" : "black"}' -H 'Content-Type: application/json' http://localhost:8080/cats
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:8080/cats/1
Content-Length: 0
Date: Wed, 14 Jan 2015 03:52:47 GMT
  • -i option shows

There’s also plenty other operation you can use to update, replace and delete. See more on the Spring Data REST documentation: http://docs.spring.io/spring-data/rest/docs/2.2.1.RELEASE/reference/html/#repository-resources.item-resource

Securing the Service

Spring Boot greatly simplifies the task of installing Spring Security. Simply add following dependency on pom.xml

                                           
  org.springframework.boot          
  spring-boot-starter-security
                                          

Next, configure Spring Security so /cats/** path are protected to users with ROLE_USER only. We also setup two in-memory users: bob with ROLE_USER and admin with ROLE_USER and ROLE_ADMIN


ty
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers("/cats/**").hasRole("USER")
        .anyRequest().anonymous().and()
      .httpBasic().and()
      .csrf().disable();
  }
  
  
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
        .withUser("bob").password("bob123").authorities("ROLE_USER").and()
        .withUser("admin").password("admin123").authorities("ROLE_USER", "ROLE_ADMIN");
  }
}

Don’t forget to recompile and restart the app. Now you can test querying the cats repository will be forbidden for non-authenticated (anonymous) users:

$ curl -i http://localhost:8080/cats
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=6F0779172E8FD7DCCFA2A71EEAB5022A; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Jan 2015 23:18:27 GMT

{"timestamp":1421277506968,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/cats"}

Let’s try authenticating using HTTP Basic as bob (password is bob123):

$ curl -i -H 'Authorization: Basic Ym9iOmJvYjEyMw==' http://localhost:8080/cats
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=A981526C9E1723F75DC553B55CCAF467; Path=/; HttpOnly
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Jan 2015 23:19:51 GMT

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/cats{?page,size,sort}",
      "templated" : true
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

The -H option passes a HTTP header as part of the request. Also note that the username and password joined by colon (:) is encoded into Base64 resulting in the string Ym9iOmJvYjEyMw==. This is the string “bob:bob123″ in plain text. You can use an to try it yourself.

Also note that similar to web browser the server gave us a JSESSIONID Cookie:

Set-Cookie: JSESSIONID=A981526C9E1723F75DC553B55CCAF467; Path=/; HttpOnly

This cookie can be used in subsequent request so you don’t have to keep re-authenticating. Let’s try creating a new Cat again to test this:

$ curl -i -X POST -d '{"name":"Tom","colour":"black"}' -H 'Cookie: JSESSIONID=A981526C9E1723F75DC553B55CCAF467' -H 'Content-Type: application/json' http://localhost:8080/cats
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:8080/cats/1
Content-Length: 0
Date: Wed, 14 Jan 2015 23:26:12 GMT

Different Security Permission for Read / Update Operations

What if you want to give ROLE_USER read-only access and full read/write to ROLE_ADMIN?

This can be achieved by using Spring Data Repository event handler class. You can invoke custom code prior / after certain operations executed on the repository. Let’s see how this works.

First enable method security on our SecurityConfig class. Add the hodSecurity(securedEnabled = true) annotation to SecurityConfig class:


ty
hodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 ...
}

Create a new CatEventHandler class annotated with Handler(Cat.class)


Handler(Cat.class)
("ROLE_ADMIN")
public class CatEventHandler {

  private static final Logger LOG = LoggerFactory.getLogger(CatEventHandler.class);
  
  e
  public void handleBeforeSave(Cat c) {
    LOG.debug("Before save " + c);
  }
  
  ate
  public void handleBeforeCreate(Cat c) {
    LOG.debug("Before create " + c);
  }
  
  kSave
  public void handleBeforeLinkSave(Cat c) {
    LOG.debug("Before link save " + c);
  }
  
  ete
  public void handleBeforeDelete(Cat c) {
    LOG.debug("Before delete " + c);
  }
  
  kDelete
  public void handleBeforeLinkDelete(Cat c) {
    LOG.debug("Before link delete " + c);
  }
}

Few important things happening here:

  • All the .. methods will be invoked before the corresponding response is given to users
  • The (“ROLE_ADMIN”) annotation will ensure only users with ROLE_ADMIN can invoke all those methods in the class (although the method has nothing in it except a logging statement)

Let’s give this a try. Authenticate as bob:bob123 again and try creating a new Cat. Error will be presented:

$ curl -i -H 'Authorization: Basic Ym9iOmJvYjEyMw==' http://localhost:8080/cats HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=796DC99B95180BCA3E10700BCA4E8BD2; Path=/; HttpOnly
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Jan 2015 23:34:09 GMT

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/cats{?page,size,sort}",
      "templated" : true
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

$ curl -i -X POST -d '{"name":"Tom","colour":"black"}' -H 'Cookie: JSESSIONID=796DC99B95180BCA3E10700BCA4E8BD2' -H 'Content-Type: application/json' http://localhost:8080/cats
HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Jan 2015 23:34:33 GMT

{"timestamp":1421278473943,"status":403,"error":"Forbidden","exception":"java.lang.IllegalStateException","message":"Access is denied","path":"/cats"}

But admin:admin123 will be able to do so just fine:

$ curl -i -H 'Authorization: Basic YWRtaW46YWRtaW4xMjM=' http://localhost:8080/cats
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=F64FE2FD9D6C9D47853B2BB03795B961; Path=/; HttpOnly
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Jan 2015 23:35:53 GMT

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/cats{?page,size,sort}",
      "templated" : true
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

$ curl -i -X POST -d '{"name":"Tom","colour":"black"}' -H 'Cookie: JSESSIONID=F64FE2FD9D6C9D47853B2BB03795B961' -H 'Content-Type: application/json' http://localhost:8080/cats
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:8080/cats/1
Content-Length: 0
Date: Wed, 14 Jan 2015 23:36:18 GMT

Let’s Make Login Easier

I find it annoying to keep having to encode our username and password into Base64. I wanted a more simplified login such as posting u=bob&p=bob123 to http://localhost:8080/login.

Let’s try doing this.

Borrowing idea from , let’s create a LoginController


("/login")
public class LoginController {

  
  private SecurityConfig securityConfig;
  
  private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
  
  private static final Logger LOG = LoggerFactory.getLogger(LoginController.class);
  
  (method = RequestMethod.POST)
  public String login(("u") String username,
    ("p") String password,
    HttpServletRequest req) throws Exception {
    
    // Force session creation so it's available to Spring Security post processor filter
    req.getSession(true);
    
    // Authenticate using AuthenticationManager configured on SecurityContext
    AuthenticationManager authMgr = securityConfig.authenticationManagerBean();
    UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(username, password);
    authReq.setDetails(authenticationDetailsSource.buildDetails(req));
    Authentication authResp = authMgr.authenticate(authReq);
    
    // If successful add the authentication response to context so the post processor filter
    // can save it to session
    SecurityContextHolder.getContext().setAuthentication(authResp);
    
    return "Authentication successful";
  }
  
  ...
}

Also create some exception handlers so login failure will produce 401 – Unauthorized HTTP status code.

  r(BadCredentialsException.class)
  (HttpStatus.UNAUTHORIZED)
  public String badCredentialsExceptionHandler(BadCredentialsException e) {
    LOG.debug("Authentication failed", e);
    return "Authentication failed: " + e.getMessage();
  }
  
  r(Exception.class)
  (HttpStatus.INTERNAL_SERVER_ERROR)
  public String exceptionHandler(Exception e) {
    LOG.debug("Authentication error", e);
    return "Authentication error: " + e.getMessage();
  }

Let’s give this baby a go:

$ curl -i -X POST -d 'u=bob&p=bob123' http://localhost:8080/login
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=A65016A06E912612701A00C51A10FE01; Path=/; HttpOnly
Accept-Charset: big5, big5-hkscs, ...
Content-Type: text/plain;charset=UTF-8
Content-Length: 25
Date: Wed, 14 Jan 2015 23:44:45 GMT

Authentication successful

Yay! Well done on making it this far. Hope you get a pretty decent looking REST API with minimal effort thanks to Spring. Don’t forget to always serve your API in HTTPS if deploying in production environment and secure it further with firewall if applicable.

As always you can browse the source code of this article on github:

Or clone it directly:

$ git clone https://github.com/gerrytan/rest1.git

Enjoy!

The Ever Confusing Business of Logging in Java

I’ve been programming Java for almost 8 years now and I still haven’t fully figured out this logging problem. Log4j, slf4j, commons-logging, JCL, JUL, logback… Why are there so many? Does this really have to be so complicated? How did we end up here? Which logging framework to use?

Let’s try to start from a humble beginning. This is essentially the problem we’re trying to solve:

System.out.println("Hello world!");

Yes.. logging is all about getting your code to produce some sort of text when an interesting event happen. The value of this can be priceless, especially when you’re debugging your code, or monitoring a production environment.

So what’s wrong with System.out.println

System.out.println is probably the easiest and most widely used logging ever, and thank God for it has taught so many new programmer how to print a text to console. But printing to console alone is not good enough, since a console can only hold so much information and the information get wiped out pretty quickly.

Also depending on the stage of your software development, a logging statement might (no longer) become useful. A System.out.println("YES this function is called"); is very useful early when you’re still writing your code, but you don’t want it to keep printing once it’s deployed to production, and you don’t want to have to recompile your code just to add/remove logging statement. Trust me, in some (poorly managed) organisations you’d be amazed to see how much fear, hysteria, anxiety and stress people get just by hearing the fact that you need to “recompile and release new version of the code”.

Enter the world of logging library

Hence why we use logging libraries. Common features of logging libraries are:

  1. Ability to assign LEVEL to your logging statement to indicate the urgency of the statement
  2. To filter logging statement only from specific subset of modules / level
  3. And to configure where the output goes: console, text file, database, etc

Here’s an example of logging statement being printed by a class:

import org.apache.log4j.Logger;

public class FiddleService() {

  private static final Logger LOG = Logger.getLogger(FiddleService.class);

  public void doFiddle() {
    LOG.debug("fiddling..");
  }

}

As you can see the class above is explicitly dependant upon log4j logging library. Apart from log4j, JUL (Java Util Logging)

Good developers don’t reinvent the wheel

Yes, we Java developers don’t like reinventing the wheel. Being one of the first cross-platform language, Java really took this concept to the next level since all of a sudden everyone can write libraries regardless what OS / processor / computers they’re running, and that library become usable by everyone else.

However sometimes this creates a situation where the same problem being solved multiple times by several competing libraries. Logging is one good example of this.

Logging libraries are unique in the sense that almost all other libraries depend on a logging library of some sort. And the lack of built-in logging abstraction in Java itself has caused all this mess.

Let’s highlight this problem with some example

My awesome app uses two libraries: meow and purr. meow uses log4j for logging, and purr uses JUL (Java Util Logging). As a result now my app pulls log4j (JUL is included in JDK) transitively. If I wanted to show certain statement, I have to constantly ask the question “Hmm.. what logging library does XYZ uses again?” which is horrifying (Consider a typical java project with 40 dependency jars).

logging

Logging Facade

So to solve this problem, Logging Facade is invented. A logging facade is not a logging library by itself, but it’s just a set of interface that allows program to interact with any logging libraries.

Logging facade allows the client application to choose whatever logging provider, and simply “bridges” the logging output there. Here’s previous example refactored with slf4j logging facade:

logging2

Note that here slf4j bridges the logging into log4j, but this is entirely configurable. You can use JUL, logback or any other libraries you like.

Why slf4j?

Indeed this is a very interesting question. Apart from log4j, the other logging facade often used is JCL (Java Commons Logging). According to Ceki (the founder of log4j, slf4j and logback), slf4j is the de-facto most used logging facade in open-source community.

So if you are asking yourself, or has been asked “which logging framework to use”. I’d say the answer is slf4j. Not because it’s the best, but simply because it’s a (most widely used) facade — it allows you (or your users/customers/clients) to use whatever logging implementation they please.

Do Not Mix Scheduler With Service

In my app I have lots of scheduled service classes implemented like this:


public FiddleService {
   private TaskScheduler scheduler;

  
  private void setupScheduler() {
    Runnable task = new Runnable() {
       public void run() {
        letsFiddle();
      }
    };
    scheduler.scheduleAtFixedRate(task, 10 * 1000);
  }

  
  public void letsFiddle() {
    ...
  }
}

At first the structure looked relatively simple, the scheduler will call letsFiddle() every 10 seconds. AOP-transaction wise I thought this should be okay since I used AspectJ mode (instead of JDK proxy).

But I just discovered this is wrong! The annotation was not effective if it’s invoked inside an inner-class.

Yep I only figured this out when strange transaction related behaviour started occuring in my app.

Few trials and errors, and I figured out the best way to implement this is to always separate the task in its own class:


public class FiddleService {
  
  public void letsFiddle() {
    ...
  }
}

public class FiddleServiceScheduler {
   private TaskScheduler scheduler;
   private FiddleService fiddleService;

  
  private void setupScheduler() {
    Runnable task = new Runnable() {
       public void run() {
        fiddleService.letsFiddle();
      }
    };
    scheduler.scheduleAtFixedRate(task, 10 * 1000);
  }  
}

This will ensure all construction-related work is done on FiddleService (possibly AOP-tx related stuff) before we invoke its transactional method

Resolving Theme Based On Domain Names On Spring Boot / Thymeleaf

Here’s my situation, I have myapp.firstdomain.com and myapp.seconddomain.com and I want my app to be styled / branded differently according to which domain used to access the app.

To keep things simple, each theme would have its own properties file with corresponding values. For example:

# src/main/resources/themes/firstdomain.properties
theme_css=/public/css/firstdomain.css
# src/main/resources/themes/seconddomain.properties
theme_css=/public/css/seconddomain.css

Next we have to register a ResourceBundleThemeSource. This tells spring where the theme specific properties file are located (in this instance we place them on themes/ folder on classpath root).

In Spring Boot, since I used automatic configuration for the web application context, additional customization has to be done via WebMvcConfigurerAdapter


public class WebMvcConfig extends WebMvcConfigurerAdapter {


  public ThemeSource themeSource() {
    ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
    themeSource.setBasenamePrefix("themes/");
    return themeSource;
  }

}

Next I need to create a ThemeResolver bean that can determine the theme based on domain names. In this instance since I used a reverse proxy, I used X-Forwarded-For HTTP header to determine the hostname, but you can simply use Host header otherwise.

This ThemeResolver keeps a map of which domain transaltes to what theme.

public class DomainNameThemeResolver extends AbstractThemeResolver {

  private Map domainNameThemeMap = new HashMap();

  
  public String resolveThemeName(HttpServletRequest request) {
    String xFwdFor = request.getHeader("x-forwarded-for");

    if(xFwdFor == null) {
      return getDefaultThemeName();
    }

    String themeName = domainNameThemeMap.get(xFwdFor.trim().toLowerCase());
    if(StringUtils.isBlank(themeName)) themeName = getDefaultThemeName();

    return themeName;

  }

  
  public void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName) {

  }

  public Map getDomainNameThemeMap() {
    return domainNameThemeMap;
  }

  public void setDomainNameThemeMap(Map domainNameThemeMap) {
    this.domainNameThemeMap = domainNameThemeMap;
  }

}

And finally, back to the WebMvcConfigurerAdapter, I also need to register this ThemeResolver bean


public ThemeResolver themeResolver() {
  DomainNameThemeResolver themeResolver = new DomainNameThemeResolver();
  themeResolver.setDefaultThemeName("firstdomain");
  themeResolver.getDomainNameThemeMap().put("myapp.firstdomain.com", "firstdomain");
  themeResolver.getDomainNameThemeMap().put("myapp.seconddomain.com", "seconddomain");
  return themeResolver;
}

The theme-specific key value pairs can then be obtained on the thymeleaf view using the special #themes.code(...) syntax. Here’s an example:

  

Note that if you’re debugging your theme resolver, Spring won’t actually invoke the resolveTheme() method unless you are actually rendering a view that needs one (eg: a jsp view that contain tag).

Enjoy!

Spring Boot Message Source Configuration

By default Spring Boot will source messages src/main/resources/messages.properteis. Specific translations for various languages can be given using the file messages_ch.properties, messages_es.properties etc. This location can be adjusted using spring.messages.basename property. See MessageSourceAutoConfiguration class for more.

Using message is a handy way to externalize something from your view. If you’re using JSP, you can inject this value like this:

  
  The app version is ${version}

Or in thymeleaf, it can be obtained directly using hash dialect:

  The app version is 

Debugging Visual C++ DLL Without Host Application EXE Source Code

Here’s our situation, the 3rd party app we’re using in our company can be customized by loading a DLL into it, but we (obviously) cannot see the source code of the host exe program, we only have access to our DLL’s source code. The problem is how to debug our DLL when crashes occured?

Yes it’s unfortunate, if the DLL did cause a crash the host exe will go down together with it. Luckily the host exe record some kind of stack trace when it crashed, here’s what it looked like (let’s call our DLL cricket.dll to simplify things):

Filename    : *******
Time        : 2014.11.13 18:41 (74:37:03 elapsed)
Program     : ******
Version     : ******
Revision    : ******
OS          : Windows 7 Server 6.1 Service Pack 1 (Build 7601)
BIOS        : DELL   - 1 - PowerEdge R420
Explorer    : 9.11
ID          : 
Processors  : 24 x Intel Xeon  E5-2420 0 @ 1.90GHz
Computer    : LIVE-SERVER-1:WORKGROUP
Memory      : 29253 free of 32690 Mb
Virtual     : 2639 free of 4095 Mb
Handlers    : 14569
Path        : D:********
Disk D:     : 169325 Mb of 224999 Mb free
Exception   : C0000005 at 70606D91 read to 1FAF001A

Modules     : 01080000 009DD000 d:************.exe (*****)
            : 775A0000 00180000 c:\windows\syswow64\ntdll.dll (6.1.7601.18247)
            : 76EB0000 00110000 c:\windows\syswow64\kernel32.dll (6.1.7601.18409)
....
            : 705F0000 00047000 cricket.dll

Pay particular attention to the Modules section at the bottom. This tells us specific address in memory where our dll was loaded by the host exe. This information will be crucial to determine the relative address further down in the stack trace.

In this instance it told us cricket.dll was loaded at 0x705F0000 and it’s of 0x00047000 bytes length.

Further down the massive stack trace, we can see the record of the particular crash-causing thread:

      crash : #213 0002EFF4 EIP: 70606D91 ESP: 23CEF448 
              70606D91:000000 [70606D91] unknown (cricket.dll)
              705FF5E1:000000 [705FF5E1] unknown (cricket.dll)
              705F90C9:000000 [705F90C9] unknown (cricket.dll)
              705FF1A2:000000 [705FF1A2] unknown (cricket.dll)
              7060D652:000000 [7060D652] unknown (cricket.dll)
              7060D6D0:000000 [7060D6D0] unknown (cricket.dll)
              76EC3378:000012 [76EC338A] AcquireSRWLockExclusive (kernel32.dll)
              775D9F0F:000063 [775D9F72] RtlInsertElementGenericTableAvl (ntdll.dll)
              775D9F0F:000036 [775D9F45] RtlInsertElementGenericTableAvl (ntdll.dll)

crash -->  70606D91 80780F00          cmp        byte [eax+0xf], 0x0
              70606D95 74EB              jz         0x70606d82

          70606D97 8B8310040000      mov        eax, [ebx+0x410]
          70606D9D 89BD24FDFFFF      mov        [ebp+0xfffffd24], edi
          70606DA3 3BF8              cmp        edi, eax
          70606DA5 740E              jz         0x70606db5

          70606DA7 663B770C          cmp        si, [edi+0xc]

What I really wanted to know here is which line of my source code corresponds to the hex code above? First, find out the relative address. In this circumstances, since the DLL was loaded at 0x705F0000, we have to subtract that amount from the address, so 0x70606D91 - 0x705F0000 (in base 16) is 0x00016D91 (you can pull up Windows calculator, set it to Programmer mode if base 16 math is too hard).

Next, prepare the DLL source code of the same version against that crashed on production environment (git tagging will be very helpful here). This also requires the .pdb file of corresponding DLL which hopefully you’ve saved when releasing the code. Keep in mind recompiling the exact same source might produce incompatible .pdb.

Drop the .pdb file into your Release folder, and from Visual Studio select Debug -> Attach to Process... It’ll be easier if you run the exe locally loaded with the exact same DLL that crashed.

Next you’ll need to translate the relative address into the local address of the exe your debugger is attached to. To do this:

  1. Open the Modules window (Debug -> Windows -> Modules)
  2. Find your DLL, take note of its start address

vcppdebug1.

Here my local DLL is loaded at 0F75000, so I just need to add that to the relative address to localize it: 0x0F75000 + 0x0x00016D91 = 0x0F766D91

Next is to find the source code corresponding to that address:

  1. Open Debug -> Windows -> Disassembly
  2. On the address bar, input the localized address 0x0F766D91
  3. Right click on the line, and select Go to Source
  4. Voila! You’ve managed locate the culprit line, now do this for the other location on the stack trace too

vcppdebug2

Big thanks to SO community for helping me with this technique.

Storing Currency Into Floating Point Type Is Not A Good Idea

Storing currency into a floating-point type seem to be the most intuitive thing to do, especially most major currency are displayed as fraction to the cents, eg: $10.50. However floating-point is designed to store fraction up into specific precision, but currency is only subdivisible until a certain amount. For example the smallest fraction is US Dollar is 1 cent, Australian Dollar 5 cent and so on. Hmm, now it sounded like storing them as integer made much more sense!

Here’s one problem I came accross recently: split a sum of money proportionally into N people. That sounded simple, until I realize if the sum cannot be divided equally, you need to take into account roundings and who get lucky to receive the remainder.

For example: divide $10 into 3 people. Each person will get $31/3.. but the problem is there isn’t any $1/3 in real life (at least in all dollar currencies I know of).

At first.. I thought I can implement the code like this:

double amount = 10.0;

double person_a = amount / 3.0;
double person_b = amount / 3.0;
double person_c = amount / 3.0;

printf("person a: $%.2f\n", person_a); // This prints the double value rounded to 2 digits after decimal
printf("person b: $%.2f\n", person_b);
printf("person c: $%.2f\n", person_c);

But this code gives me

person a: $3.33
person b: $3.33
person c: $3.33

Hey the total is only $9.99 where do the 1 cent go?

Obviously this is a rounding problem. 10.0 / 3.0 gives 3.3333333… (up until the limit of double precision), but when rounded into 3.33, we lost 0.0033333…..

Probably a more appropriate code to solve this problem is as follows:


                

int amount = 1000; // <– That is 1000 cents, ie: 10 dollar int remainder = 1000 % 3; int person_a = amount / 3; int person_b = amount / 3; int person_c = amount / 3; printf(“person a: %.2f\n”, person_a / 100.0); printf(“person b: %.2f\n”, person_b / 100.0); printf(“person c: %.2f\n”, person_c / 100.0); printf(“$%.2f remaining, who’s the lucky person?\n”, remainder / 100.0); [/c] Which gives: [text] person a: $3.33 person b: $3.33 person c: $3.33 $0.01 remaining, who’s the lucky person? [/text]

New Programming Jargons

Source: http://blog.codinghorror.com/new-programming-jargon/

1. Yoda Conditions

Yoda-conditions

Using if(constant == variable) instead of if(variable == constant), like if(4 == foo). Because it’s like saying “if blue is the sky” or “if tall is the man”.

2. Pokémon Exception Handling

Pokemon

For when you just Gotta Catch ‘Em All.

try {
}
catch (Exception ex) {
// Gotcha!
}

3. Egyptian Brackets

Egyptian

You know the style of brackets where the opening brace goes on the end of the current line, e.g. this?

if (a == b) {
printf("hello");
}

We used to refer to this style of brackets as “Egyptian brackets”. Why? Compare the position of the brackets with the hands in the picture. (This style of brackets is used in Kernighan and Ritchie’s book , so it’s known by many as K&R style.)

4. Smug Report

Pathreport-med

A bug submitted by a user who thinks he knows a lot more about the system’s design than he really does. Filled with irrelevant technical details and one or more suggestions (always wrong) about what he thinks is causing the problem and how we should fix it.

Also related to Drug Report (a report so utterly incomprehensible that whoever submitted it must have been smoking crack.), Chug Report (where the submitter is thought to have had one too many), and Shrug Report (a bug report with no error message or repro steps and only a vague description of the problem. Usually contains the phrase “doesn’t work.”)

5. A Duck

Duck-wireframe

A feature added for no other reason than to draw management attention and be removed, thus avoiding unnecessary changes in other aspects of the product.

I don’t know if I actually invented this term or not, but I am certainly not the originator of the story that spawned it.

This started as a piece of Interplay corporate lore. It was well known that producers (a game industry position, roughly equivalent to PMs) had to make a change to everything that was done. The assumption was that subconsciously they felt that if they didn’t, they weren’t adding value.

The artist working on the queen animations for Battle Chess was aware of this tendency, and came up with an innovative solution. He did the animations for the queen the way that he felt would be best, with one addition: he gave the queen a pet duck. He animated this duck through all of the queen’s animations, had it flapping around the corners. He also took great care to make sure that it never overlapped the “actual” animation.

Eventually, it came time for the producer to review the animation set for the queen. The producer sat down and watched all of the animations. When they were done, he turned to the artist and said, “that looks great. Just one thing – get rid of the duck.”

6. Refuctoring

Bottle-smashing

The process of taking a well-designed piece of code and, through a series of small, reversible changes, making it completely unmaintainable by anyone except yourself.

7. Stringly Typed

Cat-string-values

A riff on strongly typed. Used to describe an implementation that needlessly relies on strings when programmer & refactor friendly options are available.

For example:

  • Method parameters that take strings when other more appropriate types should be used.
  • On the occasion that a string is required in a method call (e.g. network service), the string is then passed and used throughout the rest of the call graph without first converting it to a more suitable internal representation (e.g. parse it and create an enum, then you have strong typing throughout the rest of your codebase).
  • Message passing without using typed messages etc.

Excessively stringly typed code is usually a pain to understand and detonates at runtime with errors that the compiler would normally find.

8. Heisenbug

unknown

Heisenbug

A computer bug that disappears or alters its characteristics when an attempt is made to study it. (Wikipedia)

9. Doctype Decoration

Charlie-brown-christmas-tree

When web designers add a doctype declaration but don’t bother to write valid markup.

Now on sale!

10. Jimmy

Jimmy

A generalized name for the clueless/new developer.

Found as we were developing a framework component that required minimal knowledge of how it worked for the other developers. We would always phrase our questions as: “What if Jimmy forgets to update the attribute?”

This led to the term: “Jimmy-proof” when referring to well designed framework code.

11. Higgs-Bugson

Higgs-boson-guy

A hypothetical bug predicted to exist based on a small number of possibly related event log entries and vague anecdotal reports from users, but it is difficult (if not impossible) to reproduce on a dev machine because you don’t really know if it’s there, and if it is there what is causing it. (see Higgs-Boson)

12. Nopping

Statue-napping

I’m writing a scifi novel from the POV of an AI, and their internal language has a lot of programming jargon in it. One of the more generalizable terms is “nopping”, which comes from assembler NOP for no-operation. It’s similar to ‘nap’, but doesn’t imply sleep, just zoning out. “Stanislav sat watching the screensaver and nopped for a while.”

13. Unicorny

Stack-overflow-unicorn

An adjective to describe a feature that’s so early in the planning stages that it might as well be imaginary. We cribbed this one from Yehuda Katz, who used it in his closing keynote at last year’s Windy City Rails to describe some of Rails’ upcoming features.

14. Baklava Code

Baklava

Code with too many layers.

Baklava is a delicious pastry made with many paper-thin layers of phyllo dough. While thin layers are fine for a pastry, thin software layers don’t add much value, especially when you have many such layers piled on each other. Each layer has to be pushed onto your mental stack as you dive into the code. Furthermore, the layers of phyllo dough are permeable, allowing the honey to soak through. But software abstractions are best when they don’t leak. When you pile layer on top of layer in software, the layers are bound to leak.

15. Hindenbug

Oh-the-huge-manatee

A catastrophic data destroying bug. “Oh the humanity!”

Also related to Counterbug (a bug you present when presented with a bug caused by the person presenting the bug) and Bloombug (a bug that accidentally generates money).

16. Fear Driven Development

Youre-fired

When project management adds more pressure (fires someone, moves deadlines forward, subtracts resources from the project, etc).

17. Hydra Code

800px-Hercules_slaying_the_Hydra

Code that cannot be fixed. Like the Hydra of legend, every new fix introduces two new bugs. It should be rewritten.

18. Common Law Feature

anonymous

Common-law-marriage

A bug in the application that has existed so long that it is now part of the expected functionality, and user support is required to actually fix it.

19. Loch Ness Monster Bug

Loch-ness-monster

I’ve started Loch Ness Monster bug for anything not reproducible / only sighted by one person. I’m hearing a lot of people in the office say it now. (Possible alternates: Bugfoot, Nessiebug.)

20. Ninja Comments

Ninja-comments

Also known as invisible commentssecret comments, or no comments.

21. Smurf Naming Convention

sal

When almost every class has the same prefix. IE, when a user clicks on the button, a SmurfAccountView passes a SmurfAccountDTO to the SmurfAccountController. The SmurfIDis used to fetch a SmurfOrderHistory which is passed to the SmurfHistoryMatch before forwarding to either SmurfHistoryReviewView or SmurfHistoryReportingView. If a SmurfErrorEvent occurs it is logged by SmurfErrorLogger to ${app}/smurf/log/smurf/smurflog.log

22. Protoduction

A prototype that ends up in production. Heard this from a tech at the Fermi lab. He said he didn’t coin the term but had heard it used a number of times at Fermi.

23. Rubber Ducking

Sometimes, you just have to talk a problem out. I used to go to my boss and talk about something and he’d listen and then I’d just answer my own question and walk out without him saying a thing. I read about someone that put a rubber duck on their monitor so they could talk to it, so rubberducking is talking your way through a problem.

24. Banana Banana Banana

Placeholder text indicating that documentation is in progress or yet to be completed. Mostly used because FxCop complains when a public function lacks documentation.

/// 
/// banana banana banana
/// 
public CustomerValidationResponse Validate()

Other food-related jargon: Programmer Fuel (Mountain Dew, coffee, Mate, anything which gets you well-caffeinated), Hot Potato (Http and Https respectively. Same number of syllables, but more fun to say), Cake (Marty’s noob cake broke the build), Chunky Salsa (based on the chunky salsa rule, a single critical error or bug that renders an entire system unusable, especially in a production environment).

25. Bicrement

Adding 2 to a variable.

26. Reality 101 Failure

The program (or more likely feature of a program) does exactly what was asked for but when it’s deployed it turns out that the problem was misunderstood and it’s basically useless.

27. Mad Girlfriend Bug

When you see something strange happening, but the software is telling you everything is fine.

28. Megamoth

Stands for MEGA MOnolithic meTHod. Often contained inside a God Object, and usually stretches over two screens in height. Megamoths of greater size than 2k LOC have been sighted. Beware of the MEGAMOTH!

29. Hooker Code

Code that is problematic and causes application instability (application “goes down” often). “Did the site go down again? Yeah, Jim must still have some hooker code in there.”

30. Jenga Code

When the whole thing collapses after you alter a block of code.

This is just the top 30, what I consider to be the most likely candidates for actual new programming jargon based on community upvotes, not just “funny thing that another programmer typed on a webpage and I felt compelled to upvote for hilarity”. Because that would be Reddit. If you’re itching to see even more, there are plenty more answers to read – three hundred and fifty six more to be precise. Longtime Stack Overflow user Greg Hewgill maintains , but this one hasn’t quite made it in there yet. In the meantime, try Stack Printer, or if you have the requisite 10k rep on Stack Overflow, you can view the full soft-deleted question on the site.