Using springloaded with multi-module Maven project

As springloaded only reload class files, in a multi module project it will only reload the main module i.e. website

I propose a workaround if you are using a Linux machine:
i.e. if you have two modules core and website

you can run

lsyncd -delay 0 -rsync /path-to-core/target/classes /path-to-website/target/website-extracted/WEB-INF/classes

This will keep syncing your class files from core to website.

Next thing you can add below line to /path-to-tomcat/bin/setenv.sh


rm /path-to-website/target/website-extracted/WEB-INF/lib/core-BUILD-0.1.jar

This would remove the jar file before apache tomcat starts.

Hope this helps.

AWS CloudFront duplicate content issue Solution

AWS Cloudfront is like proxy service, e.g. A request to Cloudfront will be served with content hosted on origin server. You chose your origin server, in the process Cloudfront will cache any files it has already served and will return the cached version for future requests.

AWS Cloudfront process:

Request -> CloudFront -> Origin Server

Origin Server -> CloudFront -> Response

 

Upon searching on internet other solutions suggest to use robot.txt, but the issue with robot.txt is that you have to make changes to your site plus it will block access to CSS and JS files too. As now Google bot are like modern browsers they need access to CSS files (to detect if your site is responsive/mobile friendly).

This solution assumes that you want to only serve static files like CSS, JS and image files.

You can use AWS Cloudfront service to cache a complete domain of your choosing, but this would create duplicate for all the content served by origin server.

So for this example we suppose that you have domain static.example.com and you are serving all its content from XXXX.cloudfront.net, this is not good SEO as it would cause duplicate content issue with search engines.

To get around the issue: once you have created your CloudFront distribution, go to “Origins” tab and add a new origin to domain say “non-existent.example.com

Once you have added a new origin to a domain that doesn’t exists any request to domain won’t get served by CloudFront.

Now go to “Behaviors” tab edit the default behavior and set origin to non existent, after this all requests to XXXX.cloudfront.net should give error(given that it is still not cached by edge locations).

Now create a new behavior with “Path Pattern” set to something like *.css for CSS files and set the origin to static.example.com, repeat this step for all the path patterns that you actually want to resolve to a successful request.

The above setup will ensure that your distribution only serve the paths patterns that you have included.

 

How to clear EhCache OnDemand

I found the following solution on Spring framework forum.

You can add following controller to your admin app, make sure the below URL is only available to you and not exposed to public.

In below code we are injecting CacheManager object, the I name used (ehCacheManager) might be different for your code.

After deploying below code visit http://localhost:8080/list-ehcache-objects and click on the cache names to clear them.


package com.mycompany.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.CacheManager;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.ParameterizableViewController;

@Controller
public class EHCacheController  {
	
	@Resource(name="ehCacheManager")
	private CacheManager cacheManager;

    /* (non-Javadoc)
     * @see org.springframework.web.servlet.mvc.ParameterizableViewController#handleRequestInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @SuppressWarnings("unchecked")
    @RequestMapping( value = "/list-ehcache-objects")
	protected String clear(Model viewModel, HttpServletRequest request, HttpServletResponse response) throws Exception {
	        HashMap model = new HashMap();
	        //Get all the active caches
	        List caches = new ArrayList(cacheManager.getCacheNames().length);
	        ArrayList cacheNamesList = new ArrayList();
	        String[] cacheNames = cacheManager.getCacheNames();
	        Iterator iter = Arrays.asList(cacheNames).iterator();
	        String cacheName = request.getParameter("cacheName");
	        while (iter.hasNext()){
	        	
	            // If the cache name has been passed from the request then flush it //
	            String cacheNameTest = (String) iter.next();
	            if (cacheNameTest.equalsIgnoreCase(cacheName)){
	                cacheManager.getCache(cacheNameTest).removeAll();
	            }
	            caches.add(cacheManager.getCache(cacheNameTest));
	            cacheNamesList.add(cacheNameTest);
	        }
	        //Stick the caches in the page model
	        model.put("caches", caches);
	        model.put("cacheNames", cacheNamesList);
	        viewModel.addAllAttributes(model);
	        return "layout/clearehcache";
	    }

    
	/**
	 * Setter for the EHCacheManager
	 * @param cacheManager
	 */
	public void setCacheManager(CacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}
	
}

For my controller view I used the following, since I am using Thymeleaf the syntax will be different to that of JSP files.

Error connecting to self generated SSL certifiate

Even now & then I run into this issue, so adding here for my own reference and everyone else.

If you are getting following error:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException

This means the server you are trying to connect to use self generated certificate, to solve this issue you need to tell JRE/JDK to trust the certificate.
To do that you need to import the SSL certificate into your JRE.

In my case I am trying to connect to SMTP over SSL, a quick service for “download smtp certificate” gave me http://notepad2.blogspot.co.uk/2012/04/import-gmail-certificate-into-java.html

To download certificate for HTTP, you can use Firefox and Internet explorer, by clicking the secure icon in address bar.

so to download the certificate for SMTP run following in console:

openssl s_client -connect smtp.gmail.com:465

Although I downloaded the certificate using port 465 but my java configuration only works on port 587 for SMTP with TLS enabled.

which outputs the certificate, e.g.

-----BEGIN CERTIFICATE----- .......... -----END CERTIFICATE-----

you can save the certificate into a file e.g.

nano smtp.gmail.com.cert

now import the certificate using:

keytool -import -trustcacerts -alias smtp.gmail.com -file /path/to/smtp.gmail.com.cert

Say “yes” to the command prompt, now you should be able to connect.

This will import the certificate to the default keystore, for me it under the home directory. As in the above command I didn’t specify a keystore, I use the same keystore e.g “~/.tomcat” for my tomcat configurations.

Also import the certificate to your JRE/JDK keystore using:

keytool -import -trustcacerts -alias smtp.gmail.com -file /path/to/smtp.gmail.com.cert -keystore $JAVA_HOME/jre/lib/security/cacerts

How to block/restrict max number of HTTP connection per IP address

I have written a simple PHP file to do that for me and I run it every 1 minute using Cron-Job.

The script needs to run as PHP-CLI (cron or command prompt) as it runs system commands and would be blocked if run as Apache script.

Here is the code.

emails to gmail undelivered from mail server

error
host gmail-smtp-in.l.google.com[74.125.67.27]
said: 550-5.7.1 [*********] The IP you're using to send mail is not
authorized to 550-5.7.1 send email directly to our servers. Please use the
SMTP relay at your 550-5.7.1 service provider instead. Learn more at
550 5.7.1 http://mail.google.com/support/bin/answer.py?answer=10336
s36si7540679anh.100 (in reply to end of DATA command)

Well the Hosting company used are assigned IP to be used for Dynamic end users e.g. ADSL. and are Reverse DNS of the mail server was to a different host. not one from which email were being sent.

actions taken to fix the issue.
1. fix the reverse DNS
2. check http://www.spamhaus.org/lookup.lasso for your IP and if listed request removal.

job done.

Type casting in PHP supported by NetBeans

A trick which can be helpful to some while trying to use intellisense in NetBeans for coding in php.

You can define a class as follows with a public static function called parse and documented to return object of type User.

class User{
/**
* @return User
*/
public static function parse($object){
return $object;
}
}

How you use it:

$object = $connectionManager->getTable('User')->find(2232);
$user = User::parse($object);

//here you can access the function of user class using intellisense feature of Netbeans.

I am not sure might be helpful to some, I personally love this trick. If you have a better suggestion please feel free to comment.