Transaction Management with Spring Transactions

Spring Transactions library is useful for transaction management in your Spring-Hibernate application. A transaction is a single unit of work, in other words – a group of database interactions that should happen together. If any one of these ‘database interactions’ fail then the changes of the previous interactions in the set should be undone.

Transactions are usually (depending on granularity) declared at the service layer of your application. Service layer is the logical place where your transaction should start and a typical service layer method would call 1 or more DAO layer methods.

Spring @Transantional annotation allows the developer to declare a transaction. The typical usage of @Transactional annotation would look like below:

@Service
public class ApplicationServiceImpl implements ApplicationService {

    private static final Logger logger = Logger.getLogger(ApplicationServiceImpl.class);

    @Autowired private ApplicationDao applicationDao;

    @Autowired private QueueDao queueDao;

    @Autowired private UserDao userDao;

    @Override
    @Transactional
    public void saveApplication(Application app) throws Exception {
        logger.info("saving app");
        applicationDao.saveApplication(app);
        queueDao.addToQueue(app);
        userDao.updateUser(app.getUser());
    }
}

Important to remember while using @Transactional is to define the condition for rollback. It is a common to incorrectly assume that because you’ve used @Transactional, Spring will take care of rolling back the whole transaction if something fails. This is not true. Spring only rolls back the transaction if your method throws an unchecked transaction i.e. Runtime Exception. It is much better practice to use the rollbackFor attribute instead. The rollbackFor attribute tells Spring what other situation (in addition to a runtime exception) to rollback for. In the example below I specify that transaction should be rolled back if any exception is thrown using attribute rollbackFor=Exception.class.


@Service
public class ApplicationServiceImpl implements ApplicationService {
private static final Logger logger = Logger.getLogger(ApplicationServiceImpl.class);
@Autowired private ApplicationDao applicationDao;

    @Autowired private QueueDao queueDao;

    @Autowired private UserDao userDao;

    @Override
    @Transactional(rollbackFor=Exception.class)
    public void saveApplication(Application app) throws Exception {
        logger.info("saving app");
        applicationDao.saveApplication(app);
        queueDao.addToQueue(app);
        userDao.updateUser(app.getUser());
    }
}

In addition to above, one way to ensure that DAO methods are always part of an existing transaction initiated at the service layer is to use propagation = Propagation.MANDATORY attribute in your DAO method. If all your transactions are initiated at the service layer it would be good idea of put this attribute on all your DAO methods. With this annotation in place, whenever a DAO method is called without the caller service starting a transaction, you would get an exception stating that no active transactions existed when method was invoked.

@Repository
public class ApplicationDaoImpl implements ApplicationDao {

    private static final Logger logger = Logger.getLogger(ApplicationDaoImpl.class);

    @Autowired private SessionFactory sessionFactory;

    @Override
    @Transactional(propagation = Propagation.MANDATORY)
    public void saveApplication(Application app) throws Exception {
        Session session = sessionFactory.getCurrentSession();
        session.save(app);
    }
}

Spring Security customising method level authorization

If you’ve used Spring Security before you’ve probably used @Secured or @PreAuthorize annotations to enable method level security. These annotations are specifically useful for preventing your web applications being attacked by malicious users. Method level security makes sure that only authorized users can execute the specific method.

Depending upon the specific problem you can either use @Secured

 @Secured({ "ROLE_DBA","ROLE_ADMIN","ROLE_SUPER_ADMIN"})
void updateUser(){

//.....

}

Or you can use @PreAuthorize

@PreAuthorize("hasRole('ADMIN', 'ROLE_DBA', 'ROLE_SUPER_ADMIN')")
void updateUser(User user){

}

However, the limitation with the above annotations is that rely on GrantedAuthorities of the in session user. In other words, you are limited to the just the roles of the user to control the access to a specific method.

What about when you want to use another attribute, lets says a STATUS determined by an external service?

Or perhaps you have there is a reasonable amount to logic involved before deciding a particular user has access to a specific controller level method of your Spring app?

Under such circumstances you can leverage the ability to call custom methods through the @PreAuthorize annotation.  You can create a custom AccessManager spring managed bean (or something else suitably named for your app)

 


@Component("accessManager")
public class AccessManager{ 

	@Autowired
	MyThirdPartyService myThirdPartyService;

	public boolean hasAccess(Authentication authentication, String... statusesNotAllowed) {
	//Complex logic can be performed here.
	//1. Access user's data with the authentication object
	//2. Access third party service to access data not available (or shouldn't be part of) in the session
	//3. statusesNotAllowed an example paramter, can have more or less
	}
}

 

The AccessManager.hasAccess() method can be called in the @PreAuthorize annotation anywhere in your application. Only when AccessManager.hasAccess method returns true with the parameters specified in the annotation, the updateUser method would get executed.


@PreAuthorize("@accessManager.hasAccess(authentication, {'CANCELLED', 'BLOCKED', 'TERMINATED'})")
public String updateUser(User user){
	....
}

 

Spring LDAP Authentication

What is LDAP? LDAP stands for Lightweight Directory Access Protocol. It’s designed to query and interact with directory data. As most enterprises use Microsoft directory service provider called Active Directory or AD, LDAP is commonly used to ‘talk’ to an Active Directory.

Developers tend to be confused about the difference between AD and LDAP. In short, AD is a database and LDAP is a protocol used to talk to an AD database.

The Java JNDI API can also be used for LDAP programming. If you’ve used JNDI API you may realize that it requires a lot more boilerplate code for even for the most simple tasks. Using Spring LDAP template on the other hand is a much more efficient way of implementing all of your LDAP related functionality.

How to use Spring-ldap? Before you write any code, you will need to import the following Spring Framework jars into your Java project. These are:

  • spring-ldap-core.jar
  • spring-core.jar and
  • spring-beans.jar

After importing the above jars, you need to create the ldapTemplate bean in spring context file. For example, I declared my ldapTemplate in the context xml as below.

  
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
 <property name="url" value="ldap://your.ad.url:389" />
 <property name="base" value="dc=your,dc=base,dc=dn" />
 <property name="userDn" value="${ad.username}" />
 <property name="password" value="${ad.password}" />
 <property name="referral" value="follow" />
 </bean>

 <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
 <constructor-arg ref="contextSource" />
 </bean>​​ 

url: the url property should be either the IP address or the URL of the Active Directory you’re using. Please make sure that you use port 689 in production. Port 689 ensures communication through LDAPS protocol which is more secure than standard LDAP. You will need to import the certificate of the Active Directory you are connecting to into your java trust store.

After you have correctly set the above properties, you will need to inject the ldapTemplate bean in your java class. In the example below I use the Spring @Autowired annotation to inject the bean into my controller class.

@Autowired LDAPTemplte ldapTemplate;

Once, you’ve injected the bean, you can finally write the java code to enable LDAP Authentication. In the snippet below I write a simple method called authenticate which authenticates a user if the correct username and password combination is supplied.


private boolean authenticate(String username, String password){
 AndFilter filter = new AndFilter();
 filter.and(new EqualsFilter("sAMAccountName", username));
 boolean authenticated = ldapTemplate.authenticate("", filter.toString(), password);
 return authenticated;
}

The above piece of code would work for you if

  • the username supplied is always be correct and
  • the user is always be enabled

This is obviously not going to be the case in real life. So we need some additional information to be returned by this method. It would nice if the method could return information related to failed password count and locked out time. This would help you understand why a user is not authenticated.

We’ll use the user search function provided by spring-ldap to return the user’s attributes. We’ll add the below code to the function we just created above.


List<Object> templates = ldapTemplate.search("", filter.toString(),new AttributesMapper() {
 @Override
 public List<Object> mapFromAttributes(Attributes attrs) throws NamingException {
 List output = new ArrayList<>();
 output.add(attrs.get("badPwdCount").get());
 output.add(attrs.get("lockoutTime").get());
 return output;
 }
});

List<Object> output = (List)templates.get(0);
logger.info("Failed Login Count: "+output.get(0).toString());
if (output.get(1) == null || output.get(1) == 0){
 logger.info("Account is not locked");
} else {
 logger.info("Account is locked")
}

The above code snippet shows how we can use the sAMAccountName attribute to search for the user. The sAMAccountName usually corresponds to the username given to the user. There is a slight chance that this might not be the case for the active directory you’re using so please just verify that sAMAccountName does actually correspond to the username used by users for logging in.

Another thing to note here is that lockoutTime returns a null value if the account has never been locked before and 0 if it’s been locked before but is not locked currently.

Obviously, the method can modified to return the values of other attributes if needed.

Firewall config for Java Web App hosted on AWS EC2 Windows 2012 server

According to AWS documentation, creating the right security group configuration should be sufficient to allow for desired communication between your AWS EC2 instance and public internet. However, that’s not quite the case when you provision a Microsoft Windows 2012 VM as an EC2 instance.

I provisioned a windows 2012 EC2 instance and opened the following ports on it (Security Group Configuration Image below).

  • Port 80 for HTTP communication
  • Port 3389 for RDP communication
  • Port 443 for HTTPS communication
  • Port 8080 for TCP communication over port 8080. This was primarily because my Java app was a Liferay web app which comes bundled together with Tomcat 8 server and deploys to port 8080 by default. You can modify server.xml to change this port.

Configure Security Group of AWS EC2 Instance

After configuring the security group settings above and provisioning the EC2 instance, I needed to be able to access a very basic web app deployed on a Tomcat 8 server from the public internet. Navigating to http://localhost:8080 worked fine from within the Windows VM, however, if I accessed http://<vm-public- ip-address>:8080 from my web browser on the public internet I was not able to navigate to the app.

Turns out the only way to fix this is to modify the windows firewall rules on the VM in addition to the security group configurations above.

To modify the firewall rules on your windows server:

  1. Navigate to Control Panel -> System and Security -> Windows Firewall
  2. Click on Advanced Settings. This should open Windows Firewall with Advanced Security windows.
Windows 2012 Firewall Rules wizard

Windows 2012 Firewall Rules wizard

  • Click on Inbound Rules. This should display all the inbound rules for the firewall on the server.
  • Click on New Rule… This should open ‘New Inbound Rule Wizard’.
  • Select ‘Port’ radio button -> Click Next -> Enter 8080, 80, 443 in ‘Specific local ports’ -> Click Next -> Select ‘allow the connection’ -> Click Next -> Click Next -> Enter “Custom Inbound rules” under Name -> Click Finish.

pic3

  • If you try to access your app web app from the public network, you should be able to access it.

Disable SSL v3 on JBoss AS 7.1.1

SSLv3 is vulnerable to POODLE attacks. If you’re running your web application on JBoss AS 7.1, you need to disable SSLv3 in order to protect your web application from POODLE attacks. JBoss AS 7.1 does support more recent versions of TLS but it is still subject to a downgrade attack i.e. the attacker tricks the browser into connecting with SSL v3.

How to test if your JBoss Server still uses SSL v3

Before attempting to disable SSL v3, you should make sure that your application can indeed be accessed via SSL v3. In order to do that:

  1. Open Internet Explorer
  2. On the browser, under options, turn off TLS 1.2, TLS 1.1, TLS 1.0 and SSL 2.0 and only allow SSL v3 (In Internet Explorer this is under Internet Options & Advanced tab)
  3. Try to access the web page of your app deployed on JBoss AS 7.1 server.
    • If you can successfully navigate to the page that means SSL v3 is enabled.
    • If you cannot navigate to the page that means SSL v3 is disbaled. This means your web application is already protected against POODLE and you don’t need to do anything.
  4. Now turn TLS back on, try to access the web page again, you should be able to access the site.
Configure IE to only use SSL v3

Configure IE to only use SSL v3

How to disable SSL v3

To disable SSLv3 in JBoss you need to make sure SSLv3 is not listed in the list of protocols in standalone.xml on your JBoss server.

  1. Open standalone.xml file
    • It is located in the configuration folder of your JBoss App server directory.
  2. Modify https connector config.
    • Change the value of protocols attribute to TLSv1, TLSv1.1, TLSv1,2.
    • Notice below in the original config – protocol list only contains TLSv1 and protocol is changed to protocols in the modified xml.

Code snippet from original configuration file.

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
        <ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="your\file\path\to\the\certificate" protocol="TLSv1"/>
</connector>

Modified code snippet.

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
        <ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="your\file\path\to\the\certificate" protocol="TLSv1,TLSv1.1,TLSv1.2"/>
</connector>

Please note that if you’re running Java 6(JDK or JRE), you can only run TLS v1.0. TLSv1.1 and TLSv1.2 require Java 7 (minimum) to be running on your server.

Liferay LDAP Export to Active Directory disabled user bug.

Liferay 6.1 LDAP tool has a bug where the Liferay user is exported into Active Directory but is disabled by default. After much deliberation I found a workaround where we can write a hook to export users instead of using the out of the box tool. The hook uses a Model Listener on the User Model to look for changes to the user object i.e. the custom code is triggered when anything about the User object changes. The custom code uses the Java JNDI interface to create and or update users in Active Directory.

	@Override
	public void onAfterCreate(User user) throws ModelListenerException {
		LDAPUtil util = new LDAPUtil();	

				try {
					log.info("Attempting to create user: Screen Name: "
							+ user.getScreenName() + " :First Name: "
							+ user.getFirstName() + " : LastName: "
							+ user.getLastName() + " Email:"
							+ user.getEmailAddress()+ " OpenID: "
					+ user.getOpenId()+ " JobTitle: "
					+ user.getJobTitle());
					util.createAdUser(user.getScreenName(),
							user.getPasswordUnencrypted(), user.getFirstName(),
							user.getLastName(), user.getEmailAddress(),
							user.getOpenId(), user.getJobTitle());

				} catch (Exception e) {
					e.printStackTrace();
					throw new ModelListenerException(e);
				}
	}

 	public void createAdUser(String screenName, String password, String firstName, String lastName, String emailAddress, String openID, String jobTitle) {
		try {

			// Create the initial directory context
			LdapContext ctx = getLdapContext();
			String userDn = getUserDN(screenName);

			// Create attributes to be associated with the new user
			Attributes attrs = new BasicAttributes(true);

			// These are the mandatory attributes for a user object
			// Note that Win2K3 will automagically create a random
			// samAccountName if it is not present. (Win2K does not)
			List<String> objectClasses =  Arrays.asList(PropsUtil.get("your.object.classes").split(","));
			for (String objectClass: objectClasses){
				attrs.put("objectClass", objectClass);
			}
			//attrs.put("samAccountName", screenName);
			
			attrs.put("cn", screenName);
			attrs.put("mail", emailAddress);
			// These are some optional (but useful) attributes
			attrs.put("givenName",firstName);
			attrs.put("sn", lastName);
			attrs.put("displayName", screenName);
			if (openID != null && openID.trim().length() > 0){
				log.info("AD User: Setting emplyeeID to: "+openID);
				attrs.put("employeeID", openID);
			}
			if (jobTitle != null && jobTitle.trim().length() > 0){
				log.info("AD User: Setting emplyeeNumber to: "+openID);
				attrs.put("employeeNumber", jobTitle);
			}
			//attrs.put("userPrincipalName", username);

			// Note that the user object must be created before the password
			// can be set. Therefore as the user is created with no
			// password, userAccountControl must be set to the following
			// otherwise the Win2K3 password filter will return error 53
			// unwilling to perform.
			attrs.put("userAccountControl", Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED + UF_ACCOUNTDISABLE));
			log.info("Creating AD user: " + userDn);
			// Create the context
			Context result = ctx.createSubcontext(userDn, attrs);
			log.info("Created account: " + userDn);

			// Set password is a ldap modfy operation
			// and we'll update the userAccountControl
			// enabling the account and forcing the password to never expire
			if (password != null) {
				ModificationItem[] mods = new ModificationItem[2];

				//Replace the "unicdodePwd" attribute with a new value
				//Password must be both Unicode and a quoted string
				String newQuotedPassword = "\"" + password + "\"";
				byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");

				mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
				mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userAccountControl", Integer.toString(UF_NORMAL_ACCOUNT + UF_DONT_EXPIRE_PASSWD)));

				// Perform the update
				ctx.modifyAttributes(userDn, mods);
				log.info("Successfully set password and updated userAccountControl");
			}

			ctx.close();

		} catch (NamingException e) {
			log.info("NamingException while creating AD user " + screenName);
			throw new RuntimeException(e);
		} catch (IOException e) {
			log.info("IOException while creating AD user " + screenName);
			throw new RuntimeException(e);
		}
	}

Integrating Liferay 6 with Active Directory through LDAP

A common requirement for enterprises is to have the ability for the users in their Active Directory to be able to login into Liferay Portal(s) with Active Directory credentials. This can be achieved in Liferay by using the Liferay LDAP tool that comes bundled together with Liferay Community Edition. This tool works well when you just want to allow AD users to login with AD credentials into Liferay. There are a number issues with exporting user from Liferay to AD but lets just focus on import for now.

Liferary integrates with AD through importing the users. This means that if user wants to be able to login into the portal his record has to be present in the Liferay User database. So whenever you enter your credentials into the login screen of a Lifray Portal integrated with AD, the LDAP tool would always check your credentials entered againsts the AD and if there is a match you will be logged in. Lets have a look at the configurations required to enable this.

  1. Login into Liferay as an admin user.
  2. Go to Control Panel -> Portal Settings -> Authentication -> LDAP.
  3. Click Add, this will open ‘ADD LDAP Server’ page.
  4. Under Server Name – <an appropriate name for the configuration>
  5. Base Provider URL: <the URL of the LDAP Server>
    1. Use port 636 if the AD allows secure LDAP connections
    2. Otherwise, port 389 for insecure LDAP connections.
  6. Base DN: <enter the distinguished name of the Base OU where Liferay LDAP would search for users>
  7. Principal: <the username of the user you’d use to connect with AD>
  8. Credentials: <password>
  9. If you click ‘Test LDAP Connection’ now, you should see a pop up suggesting that Liferay has successfully connected to the LDAP server. If the message suggests failure to connect, then please make sure your configurations are correct before moving forward.
  10. Authentication Search filter: This is the filter that Liferay LDAP would use to search for a user in AD. So if you set it to (mail=@email_address@) then liferay would search would search for the user with the supplied email address in AD. You can set multiple filters on this, for example (&(objectCategory=user)(mail=@email_address@)) would also check that the objectCategory is user in addition to matching the email address.
  11. Import Search filter: This filter is used by Liferay LDAP tool for mass import of users. I would recommend to not use mass import if you dont have to and let import only happen at user login. For example, if you set this filter to (objectCategory=user), the LDAP tool will import all users that have objectCategory of user.
  12. Screen Name: cn (Screen Name is usually mapped to the cn attribute in AD, you could map it to sAMAccountName as well depending upon your requirements).
  13. Password: userPassword
  14. Email Address: mail
  15. First Name: givenName
  16. Last Name: sn
  17. Job Title: title
  18. If you click ‘Test LDAP Users’ you should see a list of users in a pop up. If you dont see a pop up or there are no users in the pop up, this means that the configurations you entered are not correct. Please go back and check your configurations.
  19. Please make sure that the export section is blank as we are not exporting users from Liferay to AD.
  20. Press Save.

All your configurations should now be saved in PortalPreferences tables in Liferay database.

Go back to the LDAP tab now and make sure you have checked Enabled and Required checkboxes and save your changes.

If you log out and log in with a user that exists in AD you should be able to login if you’ve enterd the correct credentials.

Integrating Liferay Developer Studio with JBoss Application Server 7.1

Liferay Developer Studio comes bundled with Tomcat server. Tomcat is usually useful to get things up and running however not so suitable for resource intensive applications. JBoss is usually is good choice for most requirements. The following are the instructions on how to integrate JBoss with Liferay.

  1. Download Liferay JBoss bundle from the liferay website and save it on your local drive. I saved liferay-portal-jboss-6.2-ee-sp7-20140807114015311.zip to my local drive.
  2. Unzip this file to a folder of your choice. I unzipped it to C:\work\liferay-portal\liferay-portal-6.2-ee-sp7. This will your JBOSS_BUNDLE_HOME.
  3. Start the JBoss Server.
  4. If you navigate to http://localhost:8080/, you will see a message indicating that you dont have the Liferay License.
  5. Refer to section in my previous blog post on updating license.
  6. You also need to connect to the same database that you set up with Liferay Developer Studio. To connect to the existing database:
    1. Create a new file called portal-ext.properties in JBOSS_BUNDLE_HOME.
    2. Add the following properties to the file and restart your JBoss Application Server.
jdbc.default.driverClassName=net.sourceforge.jtds.jdbc.Driver
jdbc.default.url=jdbc:jtds:sqlserver://localhost:1433/service_portal
jdbc.default.username=xxxxxx
jdbc.default.password=xxxxxx
  1. Create a new file called portal-setup-wizard.properties in JBOSS_BUNDLE_HOME, add the following lines and save it.
    1. admin.email.from.address={your admin user email address}
    2. admin.email.from.name=Admin User
    3. liferay.home=C:/work/liferay-portal/liferay-portal-6.2-ee-sp7
    4. setup.wizard.enabled=false
  2. Create a new file called build.(your username}.properties in {LIFERAY_HOME}\liferay-developer-studio\liferay-plugins-sdk-6.2 and add the following lines and save it.
app.server.type = jboss
app.server.jboss.dir = ${app.server.parent.dir}/jboss-7.1.1
app.server.jboss.lib.global.dir = ${app.server.jboss.dir}/modules/com/liferay/portal/main
app.server.jboss.portal.dir = ${app.server.jboss.dir}/standalone/deployments/ROOT.war
app.server.jboss.deploy.dir = ${app.server.jboss.dir}/standalone/deployments
app.server.parent.dir = C:/work/liferay-portal/liferay-portal-6.2-ee-sp7
  1. Restart your application server. You should automatically be navigated to the Portal Login page.

Liferay: How to Setup Liferay 6.2 EE Developer Environment

Installing Liferey Developer Studio

  • Navigate to https://www.liferay.com/get-ee-trial/downloads/developer-studio.
  • In the Downloads section, select ‘Windows 64 Bit Bundle’ and click on download.
  • Create a folder on your machine where you want to setup your liferay environment. I have C:\work\liferay\
  • Unzip the downloaded file into the folder you created for liferay development.
  • Open Liferay Developer Studio by clicking on developer studio icon inside your unzipped folder.
  • You will be asked to specify a workspace (I specified, C:\work\liferay\workspace).
  • Start your Tomcat Server.

Updating Licence

  • Once your server has started up, navigate to http://localhost:8080. You will be automatically navigated to the page telling you that the server is not registered. To register the licence:
  • Clear both data and licence folders at LIFERAY_HOME\liferay-develoeper-studio\liferay-portal-6.2-ee-sp5\
  • Place your licence.xml in the deploy directory.
  • Restart your Tomcat Application Server.
  • You should see Liferay configuration page at http://localhost:8080

Configuring Liferay Admin User

Under the Administrator User Section:

  • Enter First Name: admin
  • Enter Last Name: user
  • Email: Enter your email address eg; rampal.abhi@gmail.com

Configure Database

Liferay comes packaged with Hypersonic database. It is recommended that you configure it to use a proper DBMS like Oracle, MySQL or SQL Server.
The following will detail the steps to connect to SQL Server.

  • Please create a new database on SQL Server and give it a sensible name, I called it liferay_portal.
  • On localhost:8080, under the database section, click on change hyperlink, this should open up a database configuration section.
  • Under Database Type dropdown select: SQL Server.
  • Under Database URL enter: jdbc:jtds:sqlserver://localhost/liferay_portal
  • Under JDBC driver class name enter: net.sourceforge.jtds.jdbc.Driver
  • Under username enter your database admin username.
  • Under password enter your database password.
  • Click Finish Configuration.

If you encounter a java connection refused exception when trying to connect to the database, please follow the following steps to resolve it.

  • Create a file called portal-ext.properties
  • Enter the following details in portal-ext.properties

jdbc.default.driverClassName=net.sourceforge.jtds.jdbc.Driver

jdbc.default.url=jdbc:jtds:sqlserver://localhost:1433/service_portal

jdbc.default.username=[your database username]

jdbc.default.password=[your database password]

  • Saved the file at LIFERAY_HOME\liferay-developer-studio\liferay-portal-6.2-ee-sp5
  • Open SQL Server Configuration Manager
  • In the left hand side menu, in the tree structure, select SQL Server Network Configuration -> Protocols for MSSQLSERVER
  • Right click on TCP/IP and enable it (if not enabled).
  • Double click on TCP/IP, this should open TCP/IP popup.
  • Open IP Addresses tab.
  • In the tab, you’ll notice a number of IP addresses listed in each section.
  • In the section where you see IP address 127.0.0.1, make sure IP is active and enabled and port is 1433.
  • Save your changes.
  • Restart the Liferay Tomcat server, you shouldn’t see any errors now.

Silicon Valley – Auckland Edition

There’s been talk by Auckland Council to transform Auckland into a technology innovation mecca in the Asia Pacific Region. Specifically, the proposal is to transform the Wynyard Quarter precinct into a mini Silicon Valley much like the actual Silicon Valley in San Francisco Bay Area in the US. It’s good to see the government recognizing the importance knowledge driven technological innovation as a source of economic growth in New Zealand. However, I feel that the government might be overlooking what really makes Silicon Valley an innovation powerhouse and its definitely not the technology parks. In fact, most companies in the valley are famously started in suburban garages or university dorm rooms. I’m not saying don’t develop technology parks, by all means, please do and get the IBMs, the HPs, the Microsofts to move in there but its going to have a limited impact on the startup scene in Auckland. To forge a culture of innovation you have to make Auckland an attractive place for young smart people from around the world to move to live and work.

The easiest thing the administration can do to attract highly mobile young bright people is to develop world class universities. Our top universities are always crying out for funding and what they receive easily dwarfs in comparison to their American and European counterparts. Once you attract top geeks from around the world to your universities, eventually some percentage of them would fuel into the local economy and even smaller percentage would try to build companies and still a smaller percentage would be successful. This will start a feedback loop, smart people would attract other smart people and eventually you would have thriving innovation centre. Secondly, you have to make Auckland a city where venture capital is easily available for startup founders. While local government can and does help with capital but ultimately this would come from the ex founders who cashed in on their successful gigs and are hungry for more. Again, this comes back to the feedback loop which is started by the pouring money into the local university system.

This is roughly the model on which startup hubs all over the world are based on. Below are some that stand out, would be nice to see people adding Auckland to that list!

Silicon Valley, US – Stanford University, University of California – Berkeley
Boston, US – Harvard University, MIT
New York, US – Columbia University, Cornell University
Waterloo/Toronto, Canada – University of Waterloo, University of Toronto
London, UK – Kings College, Imperial College, University College, London Business School, Oxbridge
Singapore – Nanyang Technological University, National University of Singapore
Tel Aviv, Israel – Tel Aviv University
Bangalore, India – Indian Institute of Science, IITs (from all over India)
Auckland, NZ – University of Auckland, Massey University??