Showing posts with label trick. Show all posts
Showing posts with label trick. Show all posts

Saturday, October 17, 2015

Trim is not removing all whitespaces in Java

Java trim is removing only ASCII whitespace characters, but ignores unicode whitespaces. This is backward compatibility thing, and there is big and detailed explanation of this problem. It can be easily fixed by using regular expression that will remove all official unicode whitespaces:
Pattern TRIM_PATTERN = Pattern.compile("^\\s*(.*?)\\s*$", Pattern.UNICODE_CHARACTER_CLASS);
Matcher matcher = TRIM_PATTERN.matcher(input);
if (matcher.matches() && matcher.groupCount() > 0) {
    return matcher.group(1);
}
return input;

But for more extreme cases you may want to use also this pattern
"^[\\s\\u2060\\u200D\\u200C\\u200B\\u180E\\uFEFF\\u00AD]*(.*?)[\\s\\u2060\\u200D\\u200C\\u200B\\u180E\\uFEFF\\u00AD]*$"

besides whitespaces it will also remove other invisible symbols.

Wednesday, September 16, 2015

Using IDE scripting console in Intellij IDEA

Some time ago, Intellij added option to write simple scripts to automate it's functions, extract information and write simple plugins. It is located under Tools / IDE scripting console. It is very basic now, just scripting file that runs inside of Intellij JVM and has access to Intellij API.

 There is simple Groovy example that automatically adds non-suspending breakpoint with log expression:

import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.xdebugger.breakpoints.SuspendPolicy

def file = LocalFileSystem.getInstance().findFileByPath("/users/test/project/src/Test.java")
def doc = FileDocumentManager.getInstance().getDocument(file)
def bp = ProjectManager.getInstance().getOpenProjects()[0].getComponent("DebuggerManager").getBreakpointManager().addLineBreakpoint(doc, 11)
bp.getXBreakpoint().setLogExpression('"test"')
bp.getXBreakpoint().setSuspendPolicy(SuspendPolicy.NONE)


Of course, this basic task can be done through XML configuration, but IDE scripting has access to much more and can do trickier tasks. There is very cool demo. Generally, from what I have seen, API is pretty impressive, it is intuitive, powerful and easy to start with.

My biggest complains are that it is pretty verbose (as Java itself), it would be great if in future versions it would be solved at least at tooling levels - with auto imports for packages, autocompletion, and more convenience functions, like attaching to actions, getting projects or files quickly. Second problem is total lack of documentation. Basically, what I have found is only GitHub repo of Intellij community edition. It has multiple modules with API scattered across them, most generic classes are under Core API.

Friday, August 14, 2015

Adding custom hostname to docker-machine VirtualBox image

When boot2docker was changed to docker-machine, it added dubious feature of being read only container, so no changes to VirtualBox will be preserved after restart. Saving changes is still perfectly fine for Linux Docker users, but not docker-machine users anymore for some reason.

So, to add new hostname before, you could just go to VirtualBox, change /etc/hosts file, and this is it - this will not work with docker-machine, as hosts file will be erased after restart. You are luckier, if you are not using net:host in docker-compose, there is special property for that too. But, if you are using net:host, the only working option is to change VirtualBox image and add this configuration:

VBoxManage modifyvm "default" --natdnshostresolver1 on

In this case it will use host machine to resolve all dns requests, even those from /etc/hosts.

Thursday, July 23, 2015

How to add configuration parameters to AWS lambda with API gateway

Unfortunately, there is no easy way to add configuration parameters to AWS lambdas, there is almost nothing in context that you can configure; there is description, but besides being ambiguous, it is not accessible from function itself. Fortunately, it is possible to set additional values from API gateway, even it is not straightforward.

When you have created API gateway mapping, go to the method screen in gateway console, there is screen with multiple boxes, one of which is called Integration Request, click it and there will be section called Mapping Templates. Add new mapping template for type application/x-www-form-urlencoded, save it, edit value and change from default Input passthrough to Mapping template, then you can transform your original request, by adding additional parameters, it uses velocity for transformation, but there is basic example:


{
  "my-new-configuration" : "my value",
  "body" : "$input.path('$')",
  "params" : "$input.params()",
  "ip" : "$context.identity.sourceIp",
  "user-agent" : "$context.identity.userAgent"
}

Besides possibility to add anything to lambda function it also has access to interesting request data like headers, ip, client type, user agent, country, etc. - all will be available in your map or pojo as parameter for lambda function. And do not forget to click Deploy API after making changes to make them live.

Friday, May 15, 2015

Erlang connection from boot2docker

If you need to connect from outside of Docker into boot2docker instance on MacOS, but nothing happens: First, make sure that all ports are mapped in VirtualBox instance - at minimum it requires 4369 and 20000-20999. Then, for hidden nodes, you may need to ping them explicitly, like:
net_adm:ping('server@127.0.0.1').

Thursday, April 9, 2015

Using Clojure dependencies without specifying version number

Clojure has mandatory version number for dependecies, so until you are a real fan of the library, you may need to look it up somewhere. Fortunately, it is possible to specify LATEST instead of version, like:
(leiningen.exec/deps '[[http-kit "LATEST"]])
...

Clojure command line script with dependencies

If you want to use Clojure for command line scripts, the easiest way is by using lein-exec plugin. It compiles clj files on the fly and downloads all necessary dependencies that are declared in same file, similarly to Groovy @Grab annotation.

For example, if you have file named download.clj with
(leiningen.exec/deps '[[http-kit "2.1.16"]])
(require '[org.httpkit.client :as http])

(prn (:body @(http/get "http://www.google.com")))


it is possible to run it by:
lein exec download.clj

Sunday, April 5, 2015

My recipe for IntelliJ IDEA distraction free mode

One of the top features in IntelliJ IDEA 14.1 is distraction free mode. I am totally in love with it and not looking back, working 100% of time in it. Biggest concern about it is: loosing tabs. I was happy with tabs before, but it looks like there is a bunch of better options:

  • Recent Files (Cmd + E) - basically dropdown with tabs, but you can also do text search in it.
  • Switcher (Ctrl + Tab) - same as Recent Files, but opens file once shortcut is released. A little faster, but you are loosing search. This is the closest to original tabs.
  • Search Everywhere (Shift + Shift) - acts as Recent Files, but if you type something - also does search for Classes, Files, Symbols, Actions, Preferences. So together with tabs it basically replaces also Cmd + E, Cmd + O, Shift + Cmd + O, Alt + Cmd + O, Shift + Cmd + A.

I chose Search Everywhere as it is most feature rich and is really awesome. I also remapped it to Ctrl + E as it includes Recent Files, but as shortcut Ctrl + E works faster and is easier to reach.

Tabs had another aspect - tabs pinning, I didn't used it a lot, but for occasional use, bookmarks replace them nicely and provide more features as can pin specific line together with file. So use F3 to bookmark and Cmd + F3 to list bookmarks.

Everything else: like splitting, navigation bar, file path, tool windows, etc. is easy accessible via shortcuts or Find Action... (Shift + Cmd + A) if you forgot shortcut.

Friday, October 31, 2014

Grails requires restart after changes in domain class

Grails officially supports domain class reloading since version 2, but recently I found problems using it together with MongoDB GORM plugin, because it required application restart after every change to domain class.
So if Hibernate is primary GORM and Mongo is used only for some particular cases, disabling it can be a good option to make development easier.

Friday, September 5, 2014

Script that logs time to JIRA from Git commit messages

If you need to report work time in JIRA and native comment hashes are not suitable for you, there is simple Groovy script that does the same and can be adjusted to particular scenario or configuration:

@GrabResolver(name='test', root='https://maven.atlassian.com/content/groups/public/')
@Grab( group ='com.atlassian.jira.plugins', module = 'jira-soapclient', version = '4.4' )
@Grab(group='org.eclipse.jgit', module='org.eclipse.jgit', version='3.3.2.201404171909-r')

import com.atlassian.jira.rpc.soap.client.JiraSoapServiceServiceLocator
import com.atlassian.jira.rpc.soap.client.RemoteWorklog
import groovy.transform.TailRecursive
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.revwalk.RevWalk
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import java.text.SimpleDateFormat
import static java.util.Calendar.*

@TailRecursive
static Set<RevCommit> subcommits(RevCommit commit, int start, RevWalk walk, def all) {
  if (commit.commitTime > start) {
    all << commit
    commit.parents.collect{ walk.parseCommit(it) }.each {
      subcommits(it, start, walk, all)
    }
  }
  return all
}

Repository repository = new FileRepositoryBuilder().setGitDir(new File(args[3])).setMustExist(true).build()
RevWalk walk = new RevWalk(repository)

def formattime = new SimpleDateFormat('yyyy-MM-dd')
formattime.setTimeZone(TimeZone.getTimeZone("UTC"))
Date start = formattime.parse(args[4])
Date end = formattime.parse(args[5])

def all = subcommits(walk.parseCommit(repository.resolve("HEAD")), start.time / 1000L as int, walk, new HashSet())
def mine = all.findAll{ it.authorIdent.name == args[6] && it.fullMessage =~ /^PRJ-[0-9]+/ }

def actual = mine.min{ it.commitTime }

def tasks = (start..end).findAll{!(it[DAY_OF_WEEK] in [SUNDAY, SATURDAY])}.collect {date ->
  actual = mine.find{ date.time / 1000L <= it.commitTime && (date + 1).time / 1000L > it.commitTime } ?: actual
  [date:date, task:(actual.fullMessage =~ /(PRJ-[0-9]+)/)[0][1]]
}

if (args[0] == 'test') {
  tasks.each { println "${it.date} - ${it.task}" }
} else if (args[0] == 'prod') {
  def jiraSoapService = new JiraSoapServiceServiceLocator().getJirasoapserviceV2(new URL('http://jira.com/rpc/soap/jirasoapservice-v2'))
  String token = jiraSoapService.login(args[1], args[2])
  tasks.each { jiraSoapService.addWorklogAndRetainRemainingEstimate(token, it.task, new RemoteWorklog(timeSpent: "8h", startDate:it.date.toCalendar())) }
}



It uses a bunch of command line parameters - first is either prod or test; test just prints tasks, prod sends them to JIRA. There is an example CLI command:

groovy gittotempo.groovy prod jirauser jirapassword c:\work\project\.git 2014-08-01 2014-08-31 gituser

Friday, May 9, 2014

Chaining jQuery promises in for cycle

JQuery has nice support for promises, but some stuff is not obvious and recently I just stuck with one particular problem: I had to prepare a bunch of closures in for cycle and added them to deferred object which was resolved afterwards. All of them had to be executed strictly one after another, but there are ajax calls so I cann't do it old fashioned way, since sinchronous ajax is weird.
So I did this:

function doPromise(someVar) {
  return function() {
    return $.ajax({ type: 'POST', url: 'http://myurl', success: doStuff, error: panic});
  }
};
function start() {
  var promise = $.Deferred();
  for (var i=0;i<10;i++) {
    promise.then(doPromise(i) );
  }
  promise.resolve();
};


And I was expecting it being called one after another, which was not the case and all of them fired simultaniously. As I found out finally, all thens are equal and I had to add them, not to original promise, but dirrectly to each other, which is a little confusing to me, but works. So this is the correct code for my case:

function start() {
  var original = $.Deferred();
  var promise = original;
  for (var i=0;i<10;i++) {
    promise = promise.then(doPromise(i) );
  }
  original.resolve();
};


Wednesday, April 30, 2014

Launching Spring Boot in Groovy with Grab

Since launch of Spring Boot I was wondering why it needs separate CLI, especially for Groovy where there is already Grab. Of course CLI provides some additional features, like reloading and out of the box dependencies, but why no one runs Boot with vanilla Groovy? So I tried it myself, and it looks like problem is that there is conflict with default Groovy libs, because standard installation includes servlet-api-2.4.jar which does not work with current Tomcat or Jetty, and as there is no anything like fork mode in Grails, there is only one way to avoid it - not to load this jar (delete it or use custom load conf).

Otherwise this works fine for me:

@Grab("org.springframework.boot:spring-boot-starter-web:1.0.2.RELEASE")
@Grab("org.springframework.boot:spring-boot-starter-actuator:1.0.2.RELEASE")
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.web.bind.annotation.*

@RestController
@EnableAutoConfiguration
class ThisWillActuallyRun {

  @RequestMapping("/")
  String home() {
    "Hello World!"
  }
}
SpringApplication.run(ThisWillActuallyRun, args)


Wednesday, April 2, 2014

Grails REST redirect after DELETE with jQuery

If you do delete from AJAX request (directly or via framework), sometimes Grails REST controller redirects response to index method, which when done with DELETE method leads to 405 HTTP error.
This happens because of incorrect content type in request. To fix it, contentType needs to be explicitly set in request, like:

$.ajax({
    url: '/todos/'+id,
    type: 'DELETE',
    contentType: 'application/json'
  })

Thursday, February 13, 2014

Storing sessions in Redis with Spring Boot

Tomcat has nice support to use Redis for session replication with this awesome library. However Spring Boot launches embedded Tomcat, so there is no traditional XML configuration, it is still super easy to change default manager to use Redis for session replication, just define containerCustomizer bean, like:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class App {
  public App() {
  }

  @Bean
  public EmbeddedServletContainerCustomizer containerCustomizer(){
    return factory -> {
      TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) factory;
      containerFactory.addContextValves(new RedisSessionHandlerValve());
      containerFactory.setTomcatContextCustomizers(Arrays.asList(context -> {
        context.setSessionTimeout(30);
        context.setManager(new RedisSessionManager(){{
          setHost("redis.server.com");
        }});
      }));
    };
  }

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

(this is syntax with new shiny Java 8 lambdas, but with few additional boring types it should compile in old Javas too).

Monday, February 3, 2014

No such property error in Cucumber specs with Geb

It is common to write Geb specs directly referencing page elements like:
  to LoginPage
  loginField << login
  passwordField << password
  loginButton.click()

But if you try doing same with Cucumber step files, you will get exception, like:
No such property: loginField for class: steps.Login_steps
groovy.lang.MissingPropertyException: No such property: loginField for class: steps.Login_steps
 at steps.Login_steps$_run_closure2.doCall(Login_steps.groovy:42)
 at ✽.When user enters login and password(Login.feature:7)

This is because page object is not bound and you should reference it explicitly, like:
  to LoginPage
  page.loginField << login
  page.passwordField << password
  page.loginButton.click()


Thursday, November 21, 2013

Script to parse groovy source code

Recently, I had to parse Groovy class to extract some information. Reflection was not good as it was not easy to get all dependencies and I had to preserve comments too. This is quite easy to do by utilizing Groovydoc internals which are part of the default libraries:


import antlr.collections.AST
import org.codehaus.groovy.antlr.AntlrASTProcessor
import org.codehaus.groovy.antlr.SourceBuffer
import org.codehaus.groovy.antlr.UnicodeEscapingReader
import org.codehaus.groovy.antlr.parser.GroovyLexer
import org.codehaus.groovy.antlr.parser.GroovyRecognizer
import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal
import org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc
import org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDocAssembler

def reader = new File("/path/to/package/org/Groovy.groovy").newReader()
SourceBuffer sourceBuffer = new SourceBuffer()
UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader, sourceBuffer)
GroovyLexer lexer = new GroovyLexer(unicodeReader)
unicodeReader.setLexer(lexer)
GroovyRecognizer parser = GroovyRecognizer.make(lexer)
parser.setSourceBuffer(sourceBuffer)
parser.compilationUnit()
AST ast = parser.getAST()

def visitor = new SimpleGroovyClassDocAssembler("/path/to/package", "org/Groovy.groovy", sourceBuffer, [], new Properties(), true)
AntlrASTProcessor traverser = new SourceCodeTraversal(visitor)
traverser.process(ast)
SimpleGroovyClassDoc doc = (visitor.getGroovyClassDocs().values() as List)[0]
doc.methods().each {
  println it.name()
  println it.commentText()
  println it.annotations()
}


This is definitely not nicest Groovy code, and looks more like Java, but gets the job done. By the way, it should be possible to parse Java too, though I didn't tried to.

Thursday, September 26, 2013

Convert color console output into HTML with Java

Some command line tools can print colored text, which looks nice in console itself (if it is supported), but not so nice when you need to show it in HTML:

[47;32mhello world

There is small console tool "aha" that can pipe such input and transform it directly in command line, but sometimes you have to do it from code. For such cases there is Java library Jansi which prints ANSI escape sequences into Windows consoles. Their less advertised feature is library for direct conversion between ANSI and HTML, which it does just fine:

@Grapes(
    @Grab(group='org.fusesource.jansi', module='jansi', version='1.11')
)

import org.fusesource.jansi.*

private String colorize(String text) throws IOException {
  new ByteArrayOutputStream().with {
    new HtmlAnsiOutputStream(it).with {
      write(text.getBytes("UTF-8"))
      close()
    }
    return new String(it.toByteArray(), "UTF-8");
  }
}

println colorize(" [47;32mhello world")

Thursday, September 5, 2013

Adding error messages to domain object in Grails

Sometimes it is more convenient to do some validation outside of the domain object, on the other side it is still nice to use standard error reporting facilities. For these cases, you can inject errors into domain objects like:

    if (someError) {
      domainobject.errors.rejectValue('param', "hasErrors")
    }
    ...
    if (!domainobject.hasErrors() && domainobject.save(flush: true)) {
    ...


Wednesday, August 28, 2013

Jenkins kills Tomcat or other Java process after job ends

Recently, I was adding new application deployment to Tomcat server that was started by Jenkins. Process was starting nicely, but was stopping at the end of the job. The only clue was log record:

Service exit with a return value of 143

This issue can be easily solved by adding -Xrs to JAVA_OPTS. Option description can be found at http://docs.oracle.com/javase/6/docs/technotes/tools/windows/java.html.


Wednesday, April 10, 2013

Setting style by custom property dynamically in AngularJS

Angular JS lets to set and update style and class based on some custom property. Unfortunately, it does not support placeholders now, for example:


<!-- This works -->
<td ng-style="myStyle">


<!-- This does not -->
<td ng-style="myStyle{{test}}">



Fortunately, it works with controller's methods, so this still can be done like:


<td ng-style="getMyStyle(test)">

where getMyStyle is controller's method.