Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Friday, February 12, 2016

Using property files with map values in Spring configuration beans

Spring and Spring Boot can map property files as configuration beans automatically. What is less known is that it can easily wire Map objects too:


@Configuration
@Component
@PropertySource("classpath:config.properties")
public class Config {
    @Value("#{${my.map}}")
    private Map map;
...





my.map={\
'key1' : 'val1', \
'key2' : 'val2', \
...




Thursday, May 29, 2014

Grabing JavaScript libraries via WebJars in Spring Boot

WebJars is nice and familiar way to work with JavaScript dependencies from Java projects. Spring Boot supports it, and it is pretty easy to add them for Groovy projects, just with good old Grab annotation, like:

@Grab("org.webjars:canjs:2.0.2")

Then all CanJS files become available under /webjars/canjs/2.0.2/. If not sure, list of files can be looked up at WebJars website.

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)


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).

Wednesday, April 24, 2013

ChannelResolutionException in Spring Integration with Groovy

Recently, after launching Spring Integration beans I got weird exception:
ChannelResolutionException: no output-channel or replyChannel header available
After some googling I found out that this error means that Spring Integration tries to configure reply channel, which in my case meant that I am replying into channel-adapter, which is not possible. So basically, problem was that my service method was defined as:
def myServiceMethod()

which Spring understands as it returns something, even if it does not. So this should be told explicitly, like:
void myServiceMethod()

and this is it.

Friday, September 28, 2012

Using Spring Security with CXF in Grails

CXF plugin is super easy way to add SOAP web service to Grails application. It creates regular service class, with few specific parameters and voila - you have SOAP. But what if you want security?
REST web services are native citizens in Grails - they are just actions in controllers, so you can use Spring Security annotations to check permissions. But there is no annotations for services. There are two easy options.
First, you can restrict actions by defining static rules. This is very simple, but not very flexible as it does not allow to configure permissions on method level, you will have to create different services for different permissions. Also, old clients may not work if WSDL requires authentication.
Second method, is to check permissions manually. In practice this is similar to annotations, and can be converted to annotations easily. There is example:


  Secret secret(int id) {
    checkRights("VIEW_SECRET")
    return Secret.get(id)
  }

  void checkRights(String rights) {
    if (!SpringSecurityUtils.ifAllGranted(rights)) {
      throw new IllegalAccessException("You don't have permission")
    }
  }

Tuesday, April 3, 2012

Accessing request parameters from UserDetailsService in Spring Security

If you need to use several properties to authenticate user with Spring Security, for example, by login and domain, there is no built-in way to do it. Even when you override UserDetailsService it only calls method with one username parameter.
Fortunately, there is easy way to access request context with Grails, so it is possible to extract any parameter you need, like:


import org.springframework.web.context.request.RequestContextHolder

class UserDetailsService implements GrailsUserDetailsService  {

  UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    def otherParameter = RequestContextHolder.requestAttributes.params.other
       ...
  }
}


Friday, October 14, 2011

InvalidClassException: GrailsUser and plugin upgrade

Recently when I tried to deploy new version of application on live server without downtime, I got error:

2011-10-14 11:02:52,058 [Tribes-Task-Receiver-4] ERROR org.apache.catalina.ha.session.DeltaManager- Manager [localhost#]: Unable to receive message through TCP channel
java.io.InvalidClassException: org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser; local class incompatible: stream classdesc serialVersionUID = -3114204362518930756, local class serialVersionUID =
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)

Basically, error is trivial, just some Spring security classes are not versioned and cluster can't synchronize users data. Fortunately, as I have found out, no hacking is needed and it can be easily fixed by upgrading spring-security-core plugin to the latest version.

To upgrade to latest version, just uninstall plugin and install it again, like:

grails uninstall-plugin spring-security-core
grails install-plugin spring-security-core

Wednesday, October 5, 2011

Calling stored procedure from JdbcTemplate

I am using JdbcTemplate to make database queries, like:
List<Map<String,Object>> rows = jdbcTemplate.queryForList("select * from rows");
Recently I had to replace SQL selects with stored procedures, but after doing so, I had exception:
java.sql.SQLException: The SQL statement must not contain a procedure call or parameter markers.
        at net.sourceforge.jtds.jdbc.JtdsStatement.executeQuery(JtdsStatement.java:1297)
        at com.mchange.v2.c3p0.impl.NewProxyStatement.executeQuery(NewProxyStatement.java:35)
        at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.java:440)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:455)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:463)
        at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:494)
As I found out finally, when queryForList is called without parameters it cann't call stored procedures, so to do it you just need to add empty parameter list:
List<Map<String,Object>> tables = jdbcTemplate.queryForList("{call getRows() }", new Object[] {});

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 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.

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 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.

Friday, February 25, 2011

Spring Integration namespaces in resources.groovy

Spring Integration relies heavily on namespaces usage, so if you need to use it, this can be easily defined in Grails Spring DSL:


beans = {
  xmlns integration:"http://www.springframework.org/schema/integration"
  xmlns mail:"http://www.springframework.org/schema/integration/mail"
  xmlns jms:"http://www.springframework.org/schema/integration/jms"

}

After that you can define your channels like:

  integration.channel(id:'inboundEmailChannel')

Thursday, February 24, 2011

Processing incoming emails with Spring Integration

Recently, I had a task to automatically process emails that come to specified address. Trivial solution is to create some periodic task with Quartz or Timer and pull new emails and process them. I googled if there is ready lib to do this and found that this can be done with Spring; or more specifically with Spring Integration. I heard about this project, but didn't payed a lot of attention to it. Main idea behind it is - this is small local ESB, so basically if you need to act on some incoming event or send some outgoing event to some system, this is nice place to look at. Another good thing is that it provides easy and out-of-the-box ready interface to many different systems, which is exactly what I was looking for email processing.
So with Spring Integration, reading email is just few beans definition (in Grails Spring DSL):


  integration.channel(id:'inboundEmailChannel')

  mail.'inbound-channel-adapter'(id:"imapAdapter",
      'store-uri':"imaps://${CH.config.logging.imap.credentials}@imap.gmail.com/INBOX",
      'java-mail-properties':['mail.imap.socketFactory.class':'javax.net.ssl.SSLSocketFactory',
            'mail.imap.socketFactory.fallback':false,
             'mail.store.protocol':'imaps', 'mail.debug':false],
      channel:"inboundEmailChannel",
      'should-delete-messages':true,
      'should-mark-messages-as-read':true,
      'auto-startup':true) {
          integration.poller('max-messages-per-poll':"1", 'fixed-rate':"5000")
   }

   integration.'service-activator'( 'input-channel':"inboundEmailChannel",
                ref:"emailService", method:"inboundEmail")


So, with this, when you have incoming email, it will call inboundEmail method of emailService.

Tuesday, June 15, 2010

Spring Roo with GWT

I tried Spring Roo recently and there are my comments about it.

Spring Roo is a tool that automates application development and configuration. It is like Maven, but Maven automates project setup and development tasks, and Spring Roo automates application development and tools integration.

Good:

1) Great idea. No doubt it is really good idea to speed up setup and scaffolding of java application. As most of them use the same set of technologies (Maven, Hibernate, JPA, Spring, Struts, jQuery, Selenium, AspectJ, JUnit) and if you have to configure everything by your own it can easily take hours (I wonder if there is competition for fastest java project setup like: fastest Maven+Struts+Spring+JPA, fastest Ant+Spring MVC+Spring+JPA). There is defenitely no need to be so.

2) Fast. No need to do it manually.

3) No dependency. At one point, there were already prebuilt setups in form of application servers, but then you have lifetime dependency on application server. With Spring Roo there is no dependency - you can loose it any time. This is also great feature. In contrast, Grails is another great tool, but also creates dependency.

Improvements:

1) Configurable tools. It is already there at some point, but what I mean it is like to have ready setups for different tools. Like setup Spring+Struts+Hibernate+Ant+jQuery application, or another setup Spring+Maven+Spring MVC+Hibernate+GWT.

2) Aspects overuse. There is one funny approach to entity files: it creates one aj file for every use case for specific. Like there is one aj file for toString method, one aj for persistence operations, one aj for properties, one aj for setters and getters, one aj for @Configurable annotation. Total 5 files per entity. I have never worked with such approach, but it looks strange to me. It is good if it at least could be configured.

Conclusion:

It is great idea. I would be totally happy if there would be tool that can create ready setup with some example stubs where I just have to pick necessary tools, like:

create helloWorld --with spring, struts, hibernate, hypersonic, junit, jquery, selenium, jpa, rest, etc.

and it generates typical helloWorld with this info. I am happy. If it can create some entities - it is totally great.

Unfortunately, I don't think that Spring will support much of rival tools like Struts, Guice, JBoss, etc. And it will make it 99% less usefull for most users.