grails (11) vaadin (11) meteor (6) java (4) elasticsearch (3) apple (2) centos (1) cloudbees (1) google analytics (1) gradle (1) heroku (1) javafx (1) javascript (1) jdbc (1) jug (1) logback (1) logging (1) mac os (1) management (1) mongodb (1) mongolab (1) mysql (1) twitter (1) ubuntu (1)

Tuesday, April 5, 2016

Application Loader - Please sign in with an app specific password. You can craeate one at appleid.apple.com.

Application Loader started showing the following message:Please sign in with an app specific password. You can craeate one at appleid.apple.com.

You have to go on this page to solve the issue (follow the steps there): https://support.apple.com/en-us/HT204397

Then you need to log out from Application Loader and sign in again with your email and the newly generated password.


TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Thursday, November 12, 2015

Performance of Java 8 lambdas and anonymous inner classes

There is a study with 55 slides by Oracle showing the performance difference between lambda and anonymous inner classes.

The most important is this slide showing that lambda is slow during warm up and as fast as anonymous classes after JIT optimizes the performance.

It does NOT mean we should avoid using lambdas. Because they have quite few proposals and ideas for performance improvements (if you want to know what, see the study) and mainly because lambas are different to anonymous inner classes. So, it just means we need to wait after JVM gets optimized. And who knows, maybe lambdas are going to be faster than anonymous inner classes.

Wednesday, October 21, 2015

Java 8 update 60 is causing "Apps that use non-public APIs will be rejected"

When you try to publish your JavaFX application into Mac App store with Java 1.8.0_60, you are going to get the following rejection.

October 18, 2015 at 5:29 PM

From Apple

2.5 - Apps that use non-public APIs will be rejected

The use of non-public APIs can lead to a poor user experience should these APIs change in the future, and is therefore not permitted. The following non-public APIs are included in your application:

From the framework: '/usr/lib/libicucore.A.dylib'

  • ubrk_getRuleStatus
  • ubrk_setUText
  • ucnv_getCanonicalName
  • ucnv_reset
  • ucol_strcollIter

If you have defined methods in your source code with the same names as the above-mentioned APIs, we suggest altering your method names so that they no longer collide with Apple's private APIs to avoid your application being flagged in future submissions.

Additionally, one or more of the above-mentioned APIs may reside in a library included with your application. If you do not have access to the library's source, you may be able to search the compiled binary using "strings" or "otool" command line tools. The "strings" tool can output a list of the methods that the library calls and "otool -ov" will output the Objective-C class structures and their defined methods. These techniques can help you narrow down where the problematic code resides.

If you are unable to reproduce this issue, ensure you are testing the exact version of the app that you submitted for review, and that you're doing so in a minimally privileged environment. See Technical Q&A QA1778: How to reproduce bugs reported against Mac App Store submissions.

For information on how to symbolicate and read a crash log, please see Technical Note TN2123 - CrashReporter.

view raw rejection.md hosted with ❤ by GitHub
The issue is that Your.app/Contents/PlugIns/Java.runtime/Contents/Home/jre/lib/libjfxwebkit.dylib libray is importing this library libicucore.A.dylib. And this issue is caused (probably) by this issue: Update to Newer Version of WebKit.

You can verify the issue by running otool for Java 1.8.0_51, 1.8.0_60 and 1.8.0_65. You will find that Java is importing that library since minor version 60.

~ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/jre/lib
~ otool -L libjfxwebkit.dylib | grep icu
# nothing is found
~ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib
~ otool -L libjfxwebkit.dylib | grep icu
/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 51.1.0)
~ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib
~ otool -L libjfxwebkit.dylib | grep icu
/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 51.1.0)
view raw test.sh hosted with ❤ by GitHub

There are 3 possible solutions.
  1. Remove libjfxwebkit.dylib from your application 
  2. If you need that library, downgrade to Java 1.8.0_51
  3. Wait after Packager cannot bundle Mac App Store Apps because JavaFX WebKit uses apple private APIs is resolved
------------------------------
Update 1:
I just got info by Martijn Verburg that these this is issue will be fixed: 
------------------------------
Update 2: 
I have got this info from mail group
The javapackager fix for JDK 8u72 does exactly this when generating .pkg files. So in short, libjfxwebkit.dylib is unchanged for 8u72, but will be excluded when generating an app for the Apple app store.
So, the solution is to remove libjfxwebkit.dylib from your .app (in case you package the  

Password and U option must have a non-empty value

You need to update xCode to 7.1 version when Application Loader throws these errors:
  • "The u option must have a non-empty value"
  • "The password option must have a non-empty value" 
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Tuesday, June 24, 2014

How to install Spark on Mac OS X


  1. Download http://spark.apache.org/downloads.html 
  2. Download http://www.scala-lang.org/download (find the version number in README inside spark archive). 
  3. Extract and add on path
    export SCALA_HOME=/Users/ondrej/scala-2.10.4
    export PATH=$PATH:$SCALA_HOME/bin
  4. Go to Spark root directory and run in command line: sbt/sbt clean assembly
  5. Then start up Spark, also from Spark root folder: ./bin/spark-shell

TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Wednesday, March 5, 2014

Commands to install and configure ElasticSearch on Ubuntu

Install ElasticSearch and Java

1  wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.1.deb
2  sudo dpkg -i elasticsearch-1.0.1.deb
3  sudo update-rc.d elasticsearch defaults 95 10
4  sudo add-apt-repository ppa:webupd8team/java
5  sudo apt-get update
6  sudo apt-get install oracle-java7-installer
7  java -version

Find out where the stuff is installed

1 dpkg --contents elasticsearch-1.0.1.deb

Configure ElasticSearch

1 df
2 sudo vi /etc/elasticsearch/elasticsearch.yml
    uncomment: bootstrap.mlockall: true
    change to you location: path.data: /mnt/elasticsearch/data
3 cd /mnt
4 sudo mkdir elasticsearch
5 cd elasticsearch/
6 sudo mkdir data
7 cd data
8 sudo mkdir elasticsearch
9 sudo chmod 777 /mnt/elasticsearch/data
10 sudo chmod 777 /mnt/elasticsearch/data/elasticsearch

Setup memory for ES (there are few ways... you could also edit ~/.profile)

1 sudo vi /usr/share/elasticsearch/bin/elasticsearch
  add (more or less depnding on your server capabilities): 
    export ES_MIN_MEM=60G
    export ES_MAX_MEM=60G

Install ES plugins

1 cd /usr/share/elasticsearch
2 sudo bin/plugin --install mobz/elasticsearch-head
3 sudo bin/plugin --install lukas-vlcek/bigdesk
4 sudo bin/plugin -i elasticsearch/marvel/latest

Run ES

1 sudo /etc/init.d/elasticsearch start
2 sudo /etc/init.d/elasticsearch stop
3 sudo /etc/init.d/elasticsearch restart
4 tail -f /var/log/elasticsearch/elasticsearch.log
view raw commands.md hosted with ❤ by GitHub
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Thursday, January 23, 2014

How to run custom Grails tests

Thanks Jan Rudovský for help with this. The code works with Grails 2.3.x. Use Custom Grails Tests for older versions.

The code below shows how to run your custom tests in functional test environment (so the application is running). For the integration tests you will need to use IntegrationTestPhaseConfigurer instead of FunctionalTestPhaseConfigurer.

eventTestPhasesStart = { phasesToRun ->
functionalTests << "phantom"
}
view raw _Events.groovy hosted with ❤ by GitHub

Friday, January 10, 2014

Who is using Vaadin plugin for Grails

We are curious who is using the plugin for integration of Vaadin into a Grails application. We could get little info based on 'likes' displayed on grails.org/plugins/vaadin, but that is not reliable.
Then we have made vaadinongrails.com page, to provide basic info about the plugin and give a few link to continue with. This page gives us better overview who is interested in the plugin. Drahomir Mach did the editorial work, many thanks for that.
The number of visitors has increased in 2013 probably due to 'Grails integration' chapter that we have included in Vaadin 7 Cookbook.

These people has helped with the plugin and they deserve our thanks. These guys helped with improvements and keeping the plugin updated: Antonio CaiazzoOkram1Christoph Frick and Clemens Schneider. Plus other guys who asked question on stackoverflow, the plugin was improved just because of questions.

Finally, a call for "action" :) 
If you are using the plugin, we would be happy if you let us know what you are building or what you would like to improve in the plugin? 


Monday, October 28, 2013

How to configure JDBC river for ElasticSearch

Updated for new version of ElasticSearch 1.0.0.

JDBC river makes possible to load data from e.g. MySql database to ElasticSearch and provide data much faster. 

Before we start, have a look at the set of jdbc-river parameters. Then you need to pick-up a strategy how to poll data from JDBC. 


PUT /_river/jdbc_river_1/_meta
{
"type" : "jdbc",
"jdbc" : {
"url": "jdbc:mysql://localhost:3306/yourDb",
"user": "login",
"password": "pass",
"sql" : "SELECT * FROM Transactions WHERE user_id = 1",
"index" : "my_jdbc_index",
"type" : "my_jdbc_type",
"bulk_size": 5000,
"max_bulk_requests": 30,
"type_mapping": {
"my_jdbc_type": {
"properties": {
"myInvoicePrice": {"type": "double"},
"customer": {"type": "string","store": true,"index": "not_analyzed"},
"created": {"type": "date","store": true},
"dataset_id": {"type": "long"}
}
}
}
}
}
}



TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

How to install ElasticSearch as a service on CentOS

The following steps were tested for ElasticSearch 0.90.5 on CentOS 6.4.
# install missing libraries (if any)
cd ~
sudo yum update
yum install java-1.7.0-openjdk.x86_64
yum install unzip
yum install mc
yum install wget
yum install curl
# get and unpack elasticsearch zip file
cd /etc
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.zip
unzip elasticsearch-0.90.5.zip
rm elasticsearch-0.90.5.zip
mv elasticsearch-0.90.5 elasticsearch
# install elasticsearch plugins
cd elasticsearch/bin
./plugin -install mobz/elasticsearch-head
./plugin -install karmi/elasticsearch-paramedic
./plugin -url http://bit.ly/GMYV9l -install river-jdbc
cd /etc/elasticsearch/lib
wget http://qiiip.org/mysql-connector-java-5.1.26-bin.jar
# make elasticsearch runnable as a service
cd ~
curl -L http://github.com/elasticsearch/elasticsearch-servicewrapper/tarball/master | tar -xz
mv *servicewrapper*/service /etc/elasticsearch/bin/
rm -Rf *servicewrapper*
sudo /etc/elasticsearch/bin/service/elasticsearch install
# set elasticsearch to run on boot
sudo /sbin/chkconfig elasticsearch on
sudo /sbin/chkconfig --list
# open port 9200 (for http) and 9300 (for tcp)
sudo iptables -L -n
iptables -A INPUT -p tcp -m tcp --dport 9200 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 9300 -j ACCEPT
service iptables save
# set min max memory variables
export ES_MIN_MEM=5G
export ES_MAX_MEM=5G
# restart server
service elasticsearch restart
tail -f /etc/elasticsearch/logs/elasticsearch.log
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Thursday, August 15, 2013

Grails and Logback: Provide default logback configuration for development environment

The main motivation is to have a custom logger setup, which every developer can easily adjust. Also, we don't want to put logback config, which is meant for developers only, on the class path.

We can place logback.xml into the root folder of our project and then pass it when running up the application
grails -Dlogback.configurationFile=logback.xml run-app
The biggest disadvantage is: it is annoying to always include additional properties in the command line and it also means you need to tell that to the new developers. Also, it is not following Grails principle "convention over configuration".

We need to provide the default configuration for the development mode if logback.configurationFile property is not set.

So we hook after compilation event as follows. Create or open scripts/_Events.groovy file in your project folder.

Here is the content of _Events.groovy file.

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.classic.joran.JoranConfigurator
import ch.qos.logback.core.ConsoleAppender
import grails.util.Environment
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.slf4j.LoggerFactory;
Log log = LogFactory.getLog("_Events")
def activateLogbackFromConfigFile = { LoggerContext loggerContext ->
JoranConfigurator configurator = new JoranConfigurator()
configurator.context = loggerContext
configurator.doConfigure('logback-config-dev.xml')
}
def activateLogbackProgrammatically = { LoggerContext loggerContext ->
PatternLayoutEncoder encoder = new PatternLayoutEncoder()
encoder.context = loggerContext
encoder.pattern = "%date{ISO8601} Thread=\"%thread\" %-5level logger=\"%logger{136}\" message=\"%msg\"%n"
encoder.start()
ConsoleAppender consoleAppender = new ConsoleAppender()
consoleAppender.name = 'console'
consoleAppender.context = loggerContext
consoleAppender.encoder = encoder
Logger rootLogger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)
rootLogger.level = Level.WARN
rootLogger.addAppender(consoleAppender)
loggerContext.getLogger("com.example").level = Level.INFO
// loggerContext.getLogger("org.codehaus.groovy.grails").level = Level.INFO
// loggerContext.getLogger("org.springframework").level = Level.INFO
// loggerContext.getLogger("org.hibernate").level = Level.INFO
// loggerContext.getLogger("net.sf.ehcache.hibernate").level = Level.INFO
// loggerContext.getLogger("org.springframework.web.client").level = Level.INFO
consoleAppender.start()
}
eventCompileEnd = {
boolean isCurrentEnvDevelopment = Environment.DEVELOPMENT.equals(Environment.currentEnvironment)
if (isCurrentEnvDevelopment) {
String logbackConfig = System.properties["logback.configurationFile"]
if (!logbackConfig) {
logbackConfig = System.env["logback.configurationFile"]
}
boolean isLogbackConfigProvided = logbackConfig != null
if (isLogbackConfigProvided) {
LogFactory.getLog("_Events").info "Logback is using: $logbackConfig"
} else {
log.info 'Logback is set for development mode. Change logback-config-dev.xml in order to adjust logging levels or change logging programmatically in _Events.groovy script.'
// if we are in dev environment and logback is not provided, use this configuration
LoggerContext loggerContext = LoggerFactory.getILoggerFactory()
loggerContext.reset()
// activateLogbackFromConfigFile loggerContext
// or you can do this for dev needs (replace doConfigure method call)
activateLogbackProgrammatically loggerContext
}
}
}
view raw _Events.groovy hosted with ❤ by GitHub
In this example logback-config-dev.xml is ment to be stored in the project root folder.

Tuesday, July 30, 2013

Meteor: How to send email from client


  1. Make sure you have got email package in projectfolder/.meteor/packages file.
    email
    view raw packages hosted with ❤ by GitHub

  2. Create server side code in order to send email (Email.send can be called only on server side). That code you can call from client later on.
    Meteor.methods({
    sendEmail: function (userId, email) {
    if (this.userId == userId) {
    Email.send(email);
    }
    }
    });
    view raw server.js hosted with ❤ by GitHub

  3. Make a template that show a link that invokes client side JavaScript that sends the email.
    <template name='welcomePage'>
    <a id='send-email-button'>Send email</a>
    </template>

  4. Make the call from the client in order to send an email.
    Template.welcomePage.events({
    'click #send-email-button': function () {
    var email = {
    to: 'xyz@failtracker.com',
    from: 'abc@failtracker.com',
    replyTo: 'abct@failtracker.com',
    subject: "test email",
    text: "hello lover boy"
    };
    Meteor.call('sendEmail', this.userId, email);
    }
    });
    view raw client.js hosted with ❤ by GitHub




Sunday, July 21, 2013

Meteor: How to login with Email, GitHub, Twitter, Google and Facebook account and add credentials to an existing user account

When an user has already an account in the Meteor application, we don't want to create another user in MongoDB when he tries to login with other OAuth service. Rather we connect the accounts and add a new login service to the existing user's services collection.

This code doesn't work for Twitter, because Twitter does not return email in the user data. Therefore, there is no way how to to connect Twitter account by email. I propose to exclude Twitter from your application until it is solved by Meteor (requestPermissions).

Also Github can have an account without email. So when user tries to login with GitHub without email, a new account is created.

Just create a new file oauth.js in server folder and copy paste the code below.

isProdEnv = function () {
if (process.env.ROOT_URL == "http://localhost:3000") {
return false;
} else {
return true;
}
}
Accounts.loginServiceConfiguration.remove({
service: 'google'
});
Accounts.loginServiceConfiguration.remove({
service: 'facebook'
});
Accounts.loginServiceConfiguration.remove({
service: 'twitter'
});
Accounts.loginServiceConfiguration.remove({
service: 'github'
});
if (isProdEnv()) {
Accounts.loginServiceConfiguration.insert({
service: 'github',
clientId: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'twitter',
consumerKey: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'google',
appId: '00000',
secret: '00000'
});
Accounts.loginServiceConfiguration.insert({
service: 'facebook',
appId: '00000',
secret: '00000'
});
} else {
// dev environment
Accounts.loginServiceConfiguration.insert({
service: 'github',
clientId: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'twitter',
consumerKey: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'google',
clientId: '11111',
secret: '11111'
});
Accounts.loginServiceConfiguration.insert({
service: 'facebook',
appId: '11111',
secret: '11111'
});
}
Accounts.onCreateUser(function (options, user) {
if (user.services) {
if (options.profile) {
user.profile = options.profile
}
var service = _.keys(user.services)[0];
var email = user.services[service].email;
if (!email) {
if (user.emails) {
email = user.emails.address;
}
}
if (!email) {
email = options.email;
}
if (!email) {
// if email is not set, there is no way to link it with other accounts
return user;
}
// see if any existing user has this email address, otherwise create new
var existingUser = Meteor.users.findOne({'emails.address': email});
if (!existingUser) {
// check for email also in other services
var existingGitHubUser = Meteor.users.findOne({'services.github.email': email});
var existingGoogleUser = Meteor.users.findOne({'services.google.email': email});
var existingTwitterUser = Meteor.users.findOne({'services.twitter.email': email});
var existingFacebookUser = Meteor.users.findOne({'services.facebook.email': email});
var doesntExist = !existingGitHubUser && !existingGoogleUser && !existingTwitterUser && !existingFacebookUser;
if (doesntExist) {
// return the user as it came, because there he doesn't exist in the DB yet
return user;
} else {
existingUser = existingGitHubUser || existingGoogleUser || existingTwitterUser || existingFacebookUser;
if (existingUser) {
if (user.emails) {
// user is signing in by email, we need to set it to the existing user
existingUser.emails = user.emails;
}
}
}
}
// precaution, these will exist from accounts-password if used
if (!existingUser.services) {
existingUser.services = { resume: { loginTokens: [] }};
}
// copy accross new service info
existingUser.services[service] = user.services[service];
existingUser.services.resume.loginTokens.push(
user.services.resume.loginTokens[0]
);
// even worse hackery
Meteor.users.remove({_id: existingUser._id}); // remove existing record
return existingUser; // record is re-inserted
}
});
view raw oauth.js hosted with ❤ by GitHub
Thanks to Gadi Cohen post.
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Meteor: Login with Github on Heroku

It is a bit tricky to setup Meteor application to login with external service on Heroku (if you want to use your own domain). You need to do the following:

  1. While creating an application on Github, you have to use the same pattern for URLs. If you choose to use www prefix, use it everywhere.
  2. Then go to the console and set ROOT_URL (heroku config:add ROOT_URL=http://www.templhub.com). You need to have it EXACTLY the same as in GitHub application configuration.

Monday, June 3, 2013

Twitter buttons in Meteor

The following steps show how to add Twitter button into a Meteor application.
  1. Add the link which represents Twitter button into the template:
  2. <template name='welcomePage'>
    <a href="https://twitter.com/intent/tweet?screen_name=TemplHub"
    class="twitter-mention-button"
    data-related="TemplHub">
    Tweet to @TemplHub
    </a>
    </template>
  3. Place the JavaScript provided by Twitter to the .js file for the template:
  4. Template.welcomePage.rendered = function () {
    addTwitterWidget();
    }
    function addTwitterWidget() {
    !function (d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0],
    p = /^http:/.test(d.location) ? 'http' : 'https';
    if (!d.getElementById(id)) {
    js = d.createElement(s);
    js.id = id;
    js.src = p + '://platform.twitter.com/widgets.js';
    fjs.parentNode.insertBefore(js, fjs);
    }
    }(document, 'script', 'twitter-wjs');
    }
    view raw welcomePage.js hosted with ❤ by GitHub
I took this code from http://templhub.com application.

Vaadin 7 and Grails: How to compile widget set

I have promised to publish a tutorial showing how to compile the widget set inside Grails project with Vaadin 7. Here you are.

  1. Create a new widget set definition file AppWidgetSet.gwt.xml in the grails-app/vaadin directory.
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE module PUBLIC
    "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN"
    "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
    <module>
    <inherits name="com.vaadin.DefaultWidgetSet" />
    <inherits name="com.example.YourWidgetset" />
    </module>
  2. Open VaadinConfig.groovy that is inside the grails-app/conf folder and add there a note about the new widgetset file.
    widgetset = "app.AppWidgetSet"
  3. Create a folder libs-widgetset (for example inside the project root folder) for libraries that are needed during the widget set compilation. Download all-in-one archive of Vaadin 7 from https://vaadin.com/download and move all the .jar files from the archive into libs-widgetset folder. Do not forgot to move also .jar files from lib folder from the archive.
  4. Create build.xml file with the following content.
    <?xml version="1.0"?>
    <project name="Widgetset compiler" basedir="." default="compile-widgetset">
    <target name="compile-widgetset">
    <path id="classpath">
    <pathelement path="grails-app/vaadin"/>
    <pathelement path="src/java"/>
    <pathelement path="target/classes"/>
    <fileset dir="libs-widgetset">
    <include name="*.jar"/>
    </fileset>
    </path>
    <echo>Compiling ${widgetset}...</echo>
    <property name="module" value="app.AppWidgetSet" />
    <property name="module.output.dir" location="web-app/VAADIN/widgetsets" />
    <property name="localWorkers" value="2" />
    <mkdir dir="${module.output.dir}" />
    <java classname="com.google.gwt.dev.Compiler" classpathref="classpath" failonerror="yes" fork="yes" maxmemory="512m">
    <arg value="-war" />
    <arg value="${module.output.dir}" />
    <arg value="-localWorkers" />
    <arg value="${localWorkers}" />
    <arg value="-strict" />
    <arg value="${module}" />
    <sysproperty key="vFailIfNotSerializable" value="true" />
    <jvmarg value="-Xss8M" />
    <jvmarg value="-XX:MaxPermSize=256M" />
    <jvmarg value="-Djava.awt.headless=true" />
    </java>
    </target>
    </project>
    view raw build.xml hosted with ❤ by GitHub
  5. Open the console inside the project root and run the ant command. The widget set compilation will start. Before you run the ant command, remove all the content of vaadin-grails-addon/web-app/VAADIN folder. 
This is a short version of tutorial "Adding Vaadin Add-on into Grails project" taken from the Vaadin 7 Cookbook.
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Sunday, May 26, 2013

How to deploy Meteor on Heroku with external MongoDB


This blog post is obsolete, use instead: http://justmeteor.com/blog/deploy-to-production-on-heroku

The case is following, you have made a Meteor application and you want to deploy it on heroku.com. Also, you want to use external MongoDB database provided by mongolab.com.
  1. Register at https://id.heroku.com/login 
  2. Install Heroku Toolbelt from https://toolbelt.heroku.com
  3. Register at https://mongolab.com/signup and create new MongoDB database (they give 500MB for free)
  4. Open the root folder of you Meteor project in console (you need a Git repository in order to deploy applications to Heroku, just set up one or use the one provided by Heroku, it becomes accesible after you create new application)
  5. Login to the Heroku from the command line: $ heroku login
  6. Create new Heroku application: 
    $ heroku create <appname> --stack cedar --buildpack https://github.com/oortcloud/heroku-buildpack-meteorite
  7. Setup other than default MongoDB for your Meteor application (you can get all the details for constructing the MONGO_URL from yours Mongolab account): 
    $ heroku config:set MONGO_URL=mongodb://<username>:<password>@ds027308.mongolab.com:27308/<dbname>
  8. Set the root URL
    $ heroku config:set ROOT_URL=http://<appname>.herokuapp.com
  9. Or this, in case you have got a domain
    heroku config:add ROOT_URL=http://yourdomain.com
  10. Add the Heroku Git repository as another remote to your git repository and push the code to that remote. The application will be automatically deployed and becomes accesible on <appname>.herokuapp.com 
    $ git remote add heroku git@heroku.com:<appname>.git
    $ git push heroku master
When you make changes to your code, just run git push heroku master again and all the commit from your origin/master will be released.

In case you want to see the response times for this setup, you can try it out on http://failtracker.com or http://templhub.com 
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Tuesday, May 21, 2013

Meteor with Google Analytics

Trying to get Google Analytics working with Meteor framework is so much fun. It took me quite some after I got this wonderful view:

How to get there: that is the question which is answered in the following gist.

Create new template, so we can hook to Template.googleAnalytics.rendered function. So, when googleAnalytics template is rendered, we can call Google Analytics service.
<template name='googleAnalytics'>
</template>
Insert the template into the HTML page that should be reported to Google Analytics.
<body>
{{> googleAnalytics}}
</body>
view raw index.html hosted with ❤ by GitHub
Implement the call to Google Analytics service as follows (just replace 'UA-111111-1' with your token).
Template.googleAnalytics.rendered = function() {
new GA('UA-111111-1');
}
GA = function(code) {
var _gaq = window._gaq || [];
_gaq.push(['_setAccount', code]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
};
Thanks to these two sources.
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.

Thursday, May 9, 2013

Vaadin 7 Cookbook

Few things I would like to share about Vaadin 7 Cookbook.
We started writing the book since Vaadin 7 alfa versions - which was hard because we needed to made a lot of changes before releasing the book. But, it gave us a lot of knowledge about Vaadin 7 and we could put it into that book. And that makes the book amazing for those who are starting with Vaadin 7. 
One of the first feedback, was "If I would be a beginner with Vaadin, this is the kind of book I’d like to study - a lot of examples that do a single thing, and everything regarding to that one thing is well explained. ... that’s how I learn new things, not by reading theoretical ramblings regarding things and stuff." - vaadin blog 
Luckily, I could participate a project where we used Vaadin 7 with Grails, which was amazing experience. Many notes are included in the book. 
Jaroslav Holan accepted my offer to be co-author, thanks to him the book is more rich for recipes that I would hardly include. Thank you for that, Jaroslav
Looking forward to hear you reflections.  

Thursday, December 27, 2012

Lazy loaded table in Vaadin 7

There are few options how to make lazy loaded table. When I say lazy loaded table then I mean a table that fetches data lazily from database.

  1. Use standard Vaadin table with scroll bar.



    Client (running in browser) loads items lazily from server (and that is awesome). But there is unfortunately no "lazy container" in Vaadin core and therefore we need to use an add-on. We can use JPAContainer for $299 USD "only". Or LazyQueryContainer for free. I tried LazyQueryContainer and worked well but I noticed that design of that add-on is a bit heavy. Therefore I have decided to build a new LazyContainer.

    Vaadin scrollable table needs to call COUNT of the selected items from a database table when rendering table and also when scrolling. There are also not efficient calls of getItemIds method from container in standard Vaadin table. It is easy to explain. When we scroll in the table then client requests data from the server. Server calls the container method getItemIds(startIndex, numberOfIds) where startIndex and numberOfIds have usually this kind of values. 

    startIndex: 0, numberOfIds: 15
    startIndex: 0, numberOfIds: 55
    startIndex: 10, numberOfIds: 72
    startIndex: 33, numberOfIds: 98

    ...

    Then we make SQL or some other kind of query to database that looks like this select * from orders limit 0 offset 15; 
    It is nice that the data is lazy loaded and therefore we don't fetch N thousands of items from database but it is wasting resources on the server. I tried to play with cache rates but I couldn't tune it to this kind of result. 

    startIndex: 0, numberOfIds: 50
    startIndex: 50, numberOfIds: 50
    startIndex: 100, numberOfIds: 50
    startIndex: 150, numberOfIds: 50
  2. We need to use PagedTable add on in order to get that kind of strict fetching data from database. But there are few problems with PagedTable. First it doesn't have good architecture and it not easy to use when we need to do localization or customization of navigation items plus there are some defects. I have fixed some of the defects, converted it to Maven project and made customization of the navigation components easier. It is accesible from forked PagedTable



    When we use PagedTable together with LazyContainer then we get quite efficient lazy loaded table. How the code of that kind of table could look like? 

    Here is the example https://github.com/ondrej-kvasnovsky/lazy-loaded-paged-table
TextLab for Mac
Ultimate application to validate, clean and format JSON, XML, SQL, HTML.