description(nullable:true, maxSize:1000000)
Monday, July 18, 2011
BLOB and TEXT type for fields in GORM
If you need long type for your fields with GORM automatic table creation, you just need to specify appropriate constraint for that field, like:
Sunday, July 17, 2011
c3p0 Connection reset error
By default c3p0 does not pings or destroys opened connections, so it will not know if database closes old connection until someone will try to use it. It leads to bad errors like:
Fortunately, this can be easily fixed as c3p0 has all necessary facilities for pinging and maintaining connections. There are several options, you can read about them in c3p0 docs, I found easiest for me asynchronously pinging waiting connections every few minutes with trivial select. For example, this will specify ping connection every 3 minute in MS SQL:
Caused by: java.sql.SQLException: I/O Error: Connection reset
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1053)
at net.sourceforge.jtds.jdbc.TdsCore.submitSQL(TdsCore.java:899)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.setAutoCommit(ConnectionJDBC2.java:2259)
at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:91)
Fortunately, this can be easily fixed as c3p0 has all necessary facilities for pinging and maintaining connections. There are several options, you can read about them in c3p0 docs, I found easiest for me asynchronously pinging waiting connections every few minutes with trivial select. For example, this will specify ping connection every 3 minute in MS SQL:
<Set name="idleConnectionTestPeriod">180</Set>
<Set name="preferredTestQuery">select 1</Set>
Saturday, July 16, 2011
Spring security in grails - roles and permissions
There is nice plugin for using Spring security in Grails - it integrates nicely in application, can be heavily customized and is easy to use. I didn't had extensive experience with Spring security before, but all security frameworks that I used, have something that represents roles and permissions. Role is group of permissions, and permissions are either defined only for groups or can be assigned to users explicitly. From first glance at Spring security there is only concept for roles (or as they called in plugin - Authorities). It confused me very much and created impression of very basic framework.
It took some time to figure out, that on the contrary - Spring security is very powerful and flexible also in this sense. Basically, all it cares is what authorities you return in your users
It took some time to figure out, that on the contrary - Spring security is very powerful and flexible also in this sense. Basically, all it cares is what authorities you return in your users
getAuthorities() method. So you can generate whatever hierarchy of permissions you want, possibly adjust it by the time or the day, or simply generate it on the fly.
Friday, July 15, 2011
Rich text component validation
Rich Text Components return HTML code, and if you are going to show it on your pages there is problem that some bad person can submit malicious HTML to your server and if you will display it "as is", this code can do something bad. So you have to check somehow that code that is submitted is generate by your component, or at least is safe. Latter is called HTML sanitization.
Simple pattern matching is too trivial, as malicious code can be hidden behind some strange unicode symbols or so (you can check how tricky it is at http://ha.ckers.org/xss.html). Basically, it usually requires parsing HTML and detecting, what can be used and what can't. Fortunately, there is already nice HTML parser built into JDK. It is intended to be used in Swing, but is abstract enough to be used for validation too. What you need to do is to extend
All validation can be done by calling static
All magic is done in
Simple pattern matching is too trivial, as malicious code can be hidden behind some strange unicode symbols or so (you can check how tricky it is at http://ha.ckers.org/xss.html). Basically, it usually requires parsing HTML and detecting, what can be used and what can't. Fortunately, there is already nice HTML parser built into JDK. It is intended to be used in Swing, but is abstract enough to be used for validation too. What you need to do is to extend
javax.swing.text.html.parser.Parser, like:import javax.swing.text.html.parser.*
import static javax.swing.text.html.HTML.Tag.*
import static javax.swing.text.html.HTML.Attribute.*
class RteParser extends Parser {
boolean hasErrors = false
public RteParser() {
super(DTD.getDTD('html'));
}
void validateTag(tag) {
...
}
void handleStartTag(TagElement tag) {
validateTag(tag)
this.flushAttributes()
}
void handleEndTag(TagElement tag) {
validateTag(tag)
this.flushAttributes()
}
void handleEmptyTag(TagElement tag) {
validateTag(tag)
this.flushAttributes()
}
public static boolean validate(String value) {
RteParser parser = new RteParser()
StringReader reader = new StringReader("<html>${value}</html>")
parser.parse(reader)
return parser.isValid()
}
public boolean isValid() {
return !hasErrors
}
}
All validation can be done by calling static
validate method.All magic is done in
validateTag. This method is specific, this is place where you check all tags and attributes against some black list or validation patterns.Wednesday, July 6, 2011
Whole object validation with Grails
There is nice field validation framework in Grails (based on Spring) with a lot of documentation.
However recently I needed to implement whole object validation (I have some rules across different fields). It is easily supported by Grails, but is not that well documented. All you need to do is to is to implement method
All errors that you have you should put into errors object, which is instance of
However recently I needed to implement whole object validation (I have some rules across different fields). It is easily supported by Grails, but is not that well documented. All you need to do is to is to implement method
beforeValidate in your domain object, like:def beforeValidate() {
if (somethingbad()) {
errors.addError("fieldname", "something bad happened")
}
}
All errors that you have you should put into errors object, which is instance of
org.springframework.validation.BeanPropertyBindingResult and you can add errors as org.springframework.validation.ObjectError instances.
Monday, July 4, 2011
Handling HTML changes via DOMSubtreeModified
Recently, I needed to handle changes in DOJO rich text editor. It supports all traditional events, but my problem was that I needed to handle also copy/pastes and especially mouse copy/pastes (right button context menu), as I have found, it does not counts as mouse events. After some investigation I have found nice, but for some reason not so popular event DOMSubtreeModified.
So I am able to handle all changes by subscribing to changes like:
One issue with this approach is that it is not supported by all browsers and is depricated by W3, but I need this feature for controlled environment.
So I am able to handle all changes by subscribing to changes like:
rte.addEventListener("DOMSubtreeModified", function(){
...
}
One issue with this approach is that it is not supported by all browsers and is depricated by W3, but I need this feature for controlled environment.
Saturday, June 25, 2011
Executable WAR and jetty:run
After creating executable WAR I have noticed that when I run application with jetty:run, there is conflict between jetty libs from maven plugin and application dependencies:
I have found that this problem can be quickly solved by using maven profiles.
All that is needed to do is to define new profile, and move all dependencies there:
Now, when you simply run
it runs without using dependencies, but when you run
2011-06-26 00:54:14.067:INFO::jetty-8.0.0.M2
2011-06-26 00:54:15.779:WARN::Failed startup of context JettyWebAppContext@5a347448@5a347448/myexecutable,file:/
java.lang.IllegalArgumentException: Object is not of type class org.eclipse.jetty.webapp.WebAppContext
at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:204)
at org.eclipse.jetty.plus.webapp.EnvConfiguration.configure(EnvConfiguration.java:98)
at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:473)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1174)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:598)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:496)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:175)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:226)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:164)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:226)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:93)
at org.eclipse.jetty.server.Server.doStart(Server.java:244)
at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:67)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:447)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:387)
at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:555)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
I have found that this problem can be quickly solved by using maven profiles.
All that is needed to do is to define new profile, and move all dependencies there:
<profiles>
<profile>
<id>myexecutablewar</id>
<activation>
<property>
<name>myexecutablewar</name>
<value>true</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jndi</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-plus</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-start</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>8.0.0.M2</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-glassfish</artifactId>
<version>2.1.v20100127</version>
</dependency>
</dependencies>
</profile>
</profiles>
Now, when you simply run
mvn jetty:run
it runs without using dependencies, but when you run
mvn install -Dmyexecutablewar=true
it uses dependencies and creates executable package.
Subscribe to:
Posts (Atom)