Wednesday, January 8, 2014

How to allow Ctrl-V pasting into Windows command line

Coming with Unix background, it's shocking to learn you cannot paste something into Windows command line using keyboard (Ctrl-V shortcut).
Luckily, there is a tool that fixes that.
Just open cmd.exe (not powershell) and run those two lines:

@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin

cinst wincommandpaste

As a bonus, you get Chocolatey installed, and this is a cool tool by itself.

Saturday, November 9, 2013

Resource versioning with Spring MVC

Since 3.0.4.RELEASE, Spring MVC provides help in managing web page static resources (images, CSS, javascripts). The most important for me was to make browser cache resources for a long time while loading the new version when the content changes. This is a best practice recommendation by YSlow and others. You just need to set a far future Expires header and change the resource URL each time the content changes.

The feature description in Spring documentation looks simple, but in reality it requires some additional work:
  • in web.xml, you should map the DispatcherServlet to root path (<url-pattern>/</url-pattern>). It was mapped to *.do previously (as usual in Spring MVC projects)
  • the location attributes relates to the root category (same level as WEB-INF). If you used to have images directory there and want to create mapping using mvc:resource, it should be like this: <mvc:resources mapping="/images/**" location="/images/" />
  • don't forget the trailing slash in the location attribute (<mvc:resources mapping="/images/**" location="/images/" />)
Now, after images are mapped everything is working just as did before. The only difference is that images are now served by Spring DispatcherServlet instead of (Tomcat) default servlet. This will incur some perfomance penaly (measure and decide if it's ok in your case!).

To introduce versioning, we need to add some string into image URLs. It could be a (Maven) version number or just whatever unique identifier. I decided to use timestamp - it's better in development environment where I have the same Maven version (1.2.3-SNAPSHOT) but the content changes all the time.

<mvc:resources mapping="/assets/#{properties['buildTime']}/**" location="/" cache-period="31556926" />

<util:map id="properties">
     <entry key="buildTime" value="${buildTimestamp}"/>
</util:map>

in pom.xml:

<properties>
     <buildTimestamp>${maven.build.timestamp}</buildTimestamp>
     <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>

make sure your Spring configuration file is filtered by Maven, so that ${buildTimestamp} gets replaced by the corresponding Maven property:

<resources>
     <resource>
         <directory>src/main/resources</directory>
     </resource>
     <resource>
         <filtering>true</filtering>
         <directory>src/main/resources</directory>
         <includes>
             <include>*.xml</include>
         </includes>
     </resource>
</resources>

The only thing left is to replace all (or some) image URLs. One possibility (as suggested by the Spring doc) is to use <spring:eval> and <spring:url> tags on each JSP page. But I very much dislike such duplicating boilerplate. So I introduced an interceptor for all pages I need:

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">
         <props>
             <!-- You servlet mappings go here ...-->
         </props>
     </property>
     <property name="interceptors" >
         <list>
             <ref bean="resourceUrlInterceptor"/>
         </list>
     </property>
</bean>

<bean id="resourceUrlInterceptor" class="com.example.interceptor.ResourceUrlInterceptor">
     <property name="properties" ref="properties" />
</bean>

And the interceptor itself is very simple:

public class ResourceUrlInterceptor extends HandlerInterceptorAdapter {

    private Map<String, String> properties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute("resourcesPath", response.encodeURL(request.getContextPath() + "/resources/" + properties.get("buildTime")));
        return true;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }
}

Finally, we can use image links like:

<img src="${resourcesPath}/images/icons/myicon.png" />

which will translate to something like:

<img src="/myapp/resources/20110725101003/images/icons/myicon.png" />

Being an old fan of Tapestry, I cannot restrain myself from demonstrating its superiority :)
In Tapestry, all you need to do is:

<img src="${context:images/icons/myicon.png}" />

Gotcha: Error handling in JSP

Struggled a lot with error handling in JSP (yeah, JSP is not my first choice).

The problem I've encountered: if an exception occurs directly in some JSP tag then:
  •  the rendered HTML appear broken at some random point
  •  the error message bypasses the application log and ends up in application server's log (localhost.log in case of Tomcat)
Example problem in JSP:

<%@ page pageEncoding="UTF-8" contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<!-- some amount of markup here -->

<fmt:formatNumber value="100" type="currency" currencyCode="${myMissingAttribute}"/>

<!-- some more markup -->


What I've found while investigating:
  1. JSP default buffer is 8k and auto flush is on. That means after rendering of each 8k chunk the result is sent back to browser. And if your error occurs later in the JSP, browser will end up with incomplete HTML.
  2. To avoid having broken HTML, you should set up big enough buffer for each page and switch auto flush off, for example: <%@ page buffer="512kb" autoFlush="false" %>
  3. And last but not least in the JSP misery list: <jsp:include> fails silently when the page path is incorrect, no errors whatsoever in ANY log !

How to easily create local SVN repository on Mac

Version control is addictive - once you get used to it, it's hard to go without, even on small temporary "pet" projects. You want to have a history of working versions to revert to if you get something totally messed up.
But what if you don't want to commit to your usual "official" repo and also don't bother to set up Assembla or something? Local repository comes to rescue!

If you are lucky to be on Mac it's a piece of cake to set up:

mkdir -p ~/repositories/svn
svnadmin create ~/repositories/svn/local

And then you can use file:///Users/yourname/repositories/svn/local as the SVN root for your projects. e.g. file:///Users/yourname/repositories/svn/local/MyProject

Win!

Monday, January 2, 2012

Attempt to prevent XSS in JSP... failed

As every web developer should know, you have to escape untrusted output to prevent Cross-site scripting vulnerabilities. Most web frameworks do it by default, but not JSP. In JSP, you have to do it manually every time, either using <c:out>...</c:out> or ${fn:escapeXml(...)}. Needless to say, it is easy to forget (especially if you are used to modern framework) and it clutters the template.

It feels logical that this problem should have been solved somehow already, given that thousands of developers have been using JSP every day, for years. But I've found only one solution that looks promising: http://pukkaone.github.com/2011/01/03/jsp-cross-site-scripting-elresolver.html.

I've given it a try and found that it basically works as expected. And the most important, you can override the escaping where needed, by using the custom tag. But there are 2 problems that prevented me from using it:

  1. The effect of this resolver is global (as expected), so you must remove existing escaping from every JSP where you have it, and re-test the whole application
  2. If you use <jsp:include> with parameters (and I use it a lot), you must override escaping of the parameter values, to avoid double escaping
So, while the first problem is solvable (given the time and resources), the second makes the whole solution look doubtful. Instead of being careful to use escaping everywhere, now I need to be careful to override escaping on each <jsp:include>. And again, it creates a lot of clutter.

Sunday, May 15, 2011

Map of Android Market supported countries, UPDATED

Good news, the Android Market has expanded list of countries where you can buy paid apps.

Click to see large image
Green countries - users can buy and developers can publish paid apps.
Blue countries - users can buy but developers cannot publish.
Yellow countries - same as blue but for some reason Google calls them "Rest of the world" (maybe some restrictions will apply).

Sadly, no new countries added to support paid apps developers.

Monday, April 4, 2011

ForkingAspect added to Common Spring Aspects

A small but useful addition to the common-spring-aspects project: forked execution of a bean method.

Using the ForkAspect, it is possible to define bean methods to be executed in a separate thread. This is useful to avoid waiting on slow methods whose results we do not actually need to proceed (common examples - email sending, statistics event registration, etc).