Thursday 31 August 2017

Input redirection with powershell

PowerShell doesn't support input redirection, so it's impossible to do sql file import in usual way without invoking legacy CMD:
PS> mysql dbname < file.sql
At line:1 char:7
+ mysql < .\file.sql
+       ~
The '<' operator is reserved for future use.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : RedirectionNotSupported

Luckily it is possible to redirect input by taking file contents, which is, probably, more natural way to do:
PS> Get-Content .\file.sql | mysql dbname

Wednesday 14 June 2017

Content Security Policy (CSP): port in domain directive

For some reason most of documentation on Content Security Policy doesn't say anything about ports in directives. I found that CSP treats domains with different ports as absolutely different domains. If you have directive like frame-ancestors 'self' *.your-client.com - it will not work if your client embedding your application from test.your-client.com:1507, your directive should be frame-ancestors 'self' *.your-client.com *.your-client.com:1507 then.

It is also possible to use "star notation" for port: frame-ancestors 'self' *.your-client.com:*

See also:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
https://content-security-policy.com/

Friday 21 April 2017

Building less from ANT without funny plugins

There are a few libraries from non-trustworthy individual developers which do compile LESS style-sheets in java, most of them are not very transparent: some of them download node.js, some of them use rhino. It is possible to do it in clear, obvious way from your ant build, see the example for Windows below.

Properties to be defined:
${your.extensions.dir} - is some dir to put NodeJS to;
${your.web.sources.dir} - is a dir for static web files, to put CSS into.

This config downloads NodeJS, installs LESS locally and compiles styles.
This example has version for Windows and MacOS, Linux version should be similar to MacOs. Node.JS can also be installed with system package manager, `_install_node` task is not needed in this case.
05 Jan 2018: updated with MacOS executables

<!-- Build less stylesheets -->
<property name="nodejs.dir" location="${your.extensions.dir}/nodejs"/>
<!-- maybe these versions should go to the ivysettings.xml, maybe not because they are not from the maven/ivy -->
<property name="nodejs.ver" value="8.9.1"/>
<property name="less.ver" value="2.7.2"/>
<if>
  <os family="windows" />
  <then>
    <property name="nodejs.archive" value="node-v${nodejs.ver}-win-x86.zip" />
    <property name="nodejs.exec.dir" location="${nodejs.dir}/node-v${nodejs.ver}-win-x86"/>
    <property name="lessc.exec" location="${nodejs.exec.dir}/lessc.cmd"/>
  </then>
  <elseif>
    <os family="mac" />
    <then>
      <property name="nodejs.archive" value="node-v${nodejs.ver}-darwin-x64.tar.gz" />
      <property name="nodejs.exec.dir" location="${nodejs.dir}/node-v${nodejs.ver}-darwin-x64/bin"/>
      <property name="lessc.exec" location="${nodejs.exec.dir}/node_modules/.bin/lessc"/>
    </then>
  </elseif>
  <else>
      <echo message="Unsupported platform, check _install_node in build.xml"/>
  </else>
</if>

<property name="less.dir" value="${your.web.sources.dir}/com/company/web/include" />

<echo message="${nodejs.exec.dir}"/>
<target name="_install_node">
    <if>
        <not><available file="${nodejs.exec.dir}"/></not>
        <then>
            <echo message="installing nodejs..."/>
            <mkdir dir="${nodejs.dir}"/>
            <get src="https://nodejs.org/dist/v${nodejs.ver}/${nodejs.archive}" dest="${nodejs.dir}" usetimestamp="false"/>
            <if>
              <os family="windows" />
              <then>
                  <unzip src="${nodejs.dir}/${nodejs.archive}" dest="${nodejs.dir}/"> </unzip>
              </then>
              <elseif>
                <os family="mac" />
                <then>
                   <untar src="${nodejs.dir}/${nodejs.archive}" dest="${nodejs.dir}/" compression="gzip"> </untar>
                   <chmod dir="${nodejs.exec.dir}" perm="ugo+rx" includes="*"/>
                </then>
              </elseif>
              <else>
                  <echo message="Unsupported platform, check _install_node in build.xml"/>
              </else>
            </if>

        </then>
        <else>
          <echo message="nodejs already installed in ${nodejs.exec.dir}"/>
        </else>
    </if>
</target>

<target name="_install_node_less" depends="_install_node">
  <if>
      <not><available file="${lessc.exec}"/></not>
      <then>
          <echo message="installing less for node from npm..."/>
          <exec dir="${nodejs.exec.dir}" executable="cmd" osfamily="Windows">
              <arg value="/c"/>
              <arg value="${nodejs.exec.dir}/npm.cmd"/>
              <arg value="install"/>
              <arg value="less@${less.ver}"/>
          </exec>
          <exec dir="${nodejs.exec.dir}" executable="npm" osfamily="mac">
              <arg value="install"/>
              <arg value="less@${less.ver}"/>
          </exec>
      </then>
  </if>
</target>

<target name="generate-styles" depends="_install_node_less">
    <echo message="compiling less to ${less.dir} ..."/>
    <!-- win executable -->
    <exec dir="${nodejs.exec.dir}" executable="cmd" osfamily="windows">
        <arg value="/c"/>
        <arg value="${lessc.exec}"/>
        <arg value="${less.dir}/base-style.less"/>
        <arg value="${less.dir}/base-style.css"/>
        <arg value="--source-map"/>
    </exec>
    <!-- mac executable -->
     <exec dir="${nodejs.exec.dir}" executable="/bin/sh" osfamily="mac">
        <arg value="-c"/>
        <arg value="${lessc.exec} --source-map ${less.dir}/base-style.less ${less.dir}/base-style.css"/>
    </exec>
</target>

Friday 7 April 2017

Windows Creators Update and compatibility of Linux subsystem with Windows binaries

Windows 10 “Creators Update” is finally available to install outside from “insiders programme”, it will soon land on most of windows 10 machine, and those who impatient can install it directly from the website: https://www.microsoft.com/en-us/software-download/windows10

Most valuable thing in this update for me is update of linux subsystem to the Ubuntu 16 and compatibility of this subsystem with Windows binaries, so you now can call pretty much any windows binary from the windows bash. (it is available in build Builds above 14951)


Unfortunately the update of subsystem is not 100% smooth, the subsystem has to be installed and re-installed back (hopefully will not be required soon).


  • (option for impatient) download “Update Now” from the https://www.microsoft.com/en-us/software-download/windows10 and install the update, the system will restart a few times.
  • After update is installed open “bash” and do “lsb_release -a” to check that you’re still on Ubuntu 14;
  • Backup any files and config from the subsystem, for example copy your ~/.bashrc to outside of the subsystem with `cp ~/.bashrc /mnt/c/temp/`
  • Exit the bash and go to windows cmd
  • Uninstall subsystem with `lxrun /uninstall`
  • Re-install linux subsystem with `lxrun /install`
  • Go to the `bash`
  • Ensure that it is now Ubuntu 16 with `lsb_release -a`
  • Try running Windows binary from the bash for example `/mnt/c/Windows/System32/ipconfig.exe /all`

This ability to seamlessly run windows binaries gives many useful opportunities, for example controlling VirtualBox virtual machines from vagrant running inside of linux subsystem.

Wednesday 15 February 2017

Spring's Autowired things to be available in constructor of JPA entity


Entities are normally not eligible for Spring-driven configuration, however it is possible to make them eligible by adding `@org.springframework.beans.factory.annotation.Configurable` annotation.

Unfortunately autowired things are not available in constructor, because they are injected after the object is constructed. Luckely `Configurable` has very useful `boolean preConstruction() default false` option to make autowired fields available in constructor. Here's the example:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.ApplicationEventPublisher;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@Configurable(preConstruction = true)
public class MyEntity {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    private String field;

    @Autowired
    private transient ApplicationEventPublisher publisher;

    public MyEntity() {
        System.out.println("do something...");
        // publisher will be null at this point
        // if preConstruction = true is not used
        publisher.publishEvent("Publish something");
        /* ... more code ... */
    }

    /* ... your code here ... */
}