Java JavaScript and CSS combining and compressing
I tried a few JavaScript combining and compression servlets and settled on Granule: https://github.com/JonathanWalsh/Granule Though the documentation is sparse, I was easily able to set it up and get it working. I encountered one problem it had with not dealing with root paths in css so I changed all mine to relative paths and it worked fine. I have yet to find out how to enable and disable debug modes with it, but sorting through the source code will hopefully reveal how to do that. My page load times have improved dramatically and allows me to keep my scripts separate for development.
Java Web Application Performance Monitoring
I found the best free java web application monitoring package around, Java Melody.
http://code.google.com/p/javamelody/
It monitors about everything you could ever want and has the simplest setup ever. It monitors your request times, jsp load times, sql query times, errors, system ram, system cpu and gives you nice charts and historical graphs of what is going on. Truly amazing. I’m loving it so far.
Spring and Hibernate fun
Getting the application content anywhere in your application:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware{
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
ApplicationContextProvider.ctx = ctx;
}
}
Getting a session factory from the application context:
SessionFactory sessionFactory = (SessionFactory) ApplicationContextProvider.getApplicationContext().getBean("mySessionFactory");
HibernateTemplate
http://static.springsource.org/spring/docs/2.5.5/api/org/springframework/orm/hibernate3/HibernateTemplate.html
Generic Dao
@Repository("GenericDAO")
@Transactional
public class GenericDaoImpl implements GenericDao {
private SessionFactory sessionFactory; // Todo: use the HibernateTemplate because it's da bomb!
private HibernateTransactionManager txManager;
private Class type;
public GenericMagentoDaoImpl() { }
public GenericMagentoDaoImpl(Class type) {
this.type = type;
sessionFactory = (SessionFactory) ApplicationContextProvider.getApplicationContext().getBean("magentoSessionFactory");
}
@Override
public PK save(T o) {
Session session = sessionFactory.openSession();
try {
return (PK) session.save(o);
} finally {
session.close();
}
}
@Override
public T get(PK id) {
Session session = sessionFactory.openSession();
try {
return (T) session.get(type, id);
} finally {
session.close();
}
}
@Override
public void update(T o) {
Session session = sessionFactory.openSession();
try {
session.update(o);
} finally {
session.close();
}
}
@Override
public void delete(T o) {
Session session = sessionFactory.openSession();
try {
session.delete(o);
} finally {
session.close();
}
}
@Override
public List executeNamedQuery(String queryName, HashMap queryArgs) {
Session session = sessionFactory.openSession();
try {
final Query namedQuery = session.getNamedQuery(queryName);
//String[] namedParameters = namedQuery.getNamedParameters();
for(String key : queryArgs.keySet()) {
namedQuery.setParameter(key, queryArgs.get(key));
}
return (List) namedQuery.list();
} finally {
session.close();
}
}
@Override
public List executeNamedQueryWithLimit(String queryName, HashMap queryArgs, int limit) {
Session session = sessionFactory.openSession();
List list = new ArrayList();
try {
session.beginTransaction();
final Query namedQuery = session.getNamedQuery(queryName);
//String[] namedParameters = namedQuery.getNamedParameters();
for(String key : queryArgs.keySet()) {
namedQuery.setParameter(key, queryArgs.get(key));
}
namedQuery.setMaxResults(limit);
list = namedQuery.list();
session.getTransaction().commit();
} finally {
session.close();
}
return list;
}
}
import java.io.Serializable;
import java.util.*;
public interface GenericDao {
/** Persist the newInstance object into database */
PK save(T newInstance);
/** Retrieve an object that was previously persisted to the database using the indicated id as primary key */
T get(PK id);
/** Save changes made to a persistent object. */
void update(T transientObject);
/** Remove an object from persistent storage in the database */
void delete(T persistentObject);
public List executeNamedQuery(String queryName, HashMap queryArgs);
public List executeNamedQueryWithLimit(String queryName, HashMap queryArgs, int limit);
}
Cross domain add product to cart in Magento in IE
Recently we ran into an issue at work where Magento 1.3 would not hold a session in Internet Explorer when using the add to cart action in the checkout module. We created our own action, in our own controller, in our own module and had the same problem. Finally we realized that we need a trailing slash to stop Magento from redirecting in and losing the session in IE.
Spring MVC and Hibernate
My current Spring MVC and Hibernate project is located at:
http://shelfreliancepro.com
Shelf Reliance Pro (SRPro) is a customer relationship management system for consultants of Shelf Reliance. The system not only helps consultants manage their contacts, but it helps them manage their time and auto-generates tasks to help be an effective consultant. The app includes and address book, calendaring, task management and many more features. Communication features will also be made available in time. The introductory level is free until a consultant has a certain number of contacts. Higher levels will provide more features for the user as well.
It is currently hosted on a free Amazon EC2 cloud instance, so the performance isn’t what it could be at the moment, but it is on that server for development and beta testing. The server only consists of one CPU and 600 MB RAM, but Jboss 7 and Spring MVC can still run on it.
Expect the site to be up and down during development.
JBoss 7
I’ve recently switch from using Glassfish to Jboss 7 as my go to Java Server. Jboss 7 releases have names like ‘Zap’ and ‘Lightning’ and it lives up to it’s name. It starts fast, and loads applications fast. A standalone mode and domain mode is available depending on what setup you want to use. I’ve been very impressed. The last time I used Jboss was back in version 3 and they have made huge improvements with it.
What is lacking:
Netbeans Integration for debugging (Still stuck with glassfish for this)
I’m keeping a close eye on this Netbeans issue:
http://netbeans.org/bugzilla/show_bug.cgi?id=200132
Of course any Java server isn’t meant to sit out on the front lines, so I but Nginx out front to serve up all static content and handle SSL.
Java FX 2.0
I’ve recently been able to try out Java FX 2.0 Beta. I’m happy to say that I like that the Java FX Script is gone and now native Java is used. Learning a new scripting language shouldn’t have to be necessary to pick up a new Java technology. They still have the Java FX XML layouts so you can edit view layouts on the fly.
A few things lacking right now:
Mobile support
In browser support – the runtime links are broken on Oracle’s site
Netbeans GUI Builder
I hope the official release comes out soon and supports these things so that Java FX 2.0 can be used in production.
Nginx Reverse Proxy Redirect
Here’s an example conf file for Nginx doing a reverse proxy redirect and also a static content serving setup:
user www-data www-data;
worker_processes 2;
events {
worker_connections 1024;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name somesite.com;
# send all requests to https
rewrite ^(.*) https://$server_name$1 permanent;
location /resources {
root /var/www;
index index.html index.htm;
}
location / {
proxy_pass http://127.0.0.1:881;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
error_page 403 404 /40x.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 443;
server_name somesite.com;
gzip on;
ssl on;
ssl_certificate /root/cert/certificate.crt;
ssl_certificate_key /root/cert/certkey.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /resources {
root /var/www;
index index.html index.htm;
}
location / {
proxy_pass http://127.0.0.1:881;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
error_page 403 404 /40x.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location = /40x.html {
root html;
}
}
}
Spring MVC Annotation Scheduled Tasks/Cron
Spring MVC makes it easy to execute cron jobs within your application.
Step one:
Add the following to your spring-servlet.xml file:
<!-- Configures the @Scheduled programming model --> <task:annotation-driven />
Also make sure this is in your beans tag:
xsi:schemaLocation=" http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
Next create a component class with this annotation:
@Component
class Scheduler {
Finally:
Tag methods with one of these annotations to scheduled it’s run time:
@Scheduled(cron="0 0 * * * *") // Every hour on the hour
public void runMe() { }
@Scheduled(fixedDelay = 3600000) // Hour increments from last stop
public void runRunRudolf() { }
The cron is a little different from Linux crons in that it has a seconds field which gives you fine grain control of when these run. Be sure to catch all exceptions in the scheduled tasks or the task could restart and cause unwanted behavior.
Using Action inheritance to enhance Struts applications
Previously, the web application I work with had all Action classes inherit from the Strut’s Action class. We noticed that on each request, all our actions had to do some user authentication and error catching and EJB session facade creating. Many new actions that were created neglected proper checking. We decided to create our own base abstract action classes for our action classes to inherit from. The base abstract action classes inherit from the Strut’s Action class and implement the ‘execute’ method. Within the execute method we put the authentication checking code and set variables to hold the request, response, and frequently used session facades. The execute method also declares an abstract method called either getJSON or getMapping to perform the action and return the forwarding location to the view/jsp or else a JSON object to be returned to an AJAX call.
We implemented the new abstract base classes and changed all our action classes to inherit from them. Not only did we enhance the security and consistency of the system, but we reduced the code base by hundreds of lines of code.
Note: Only one instance of each Action class is generated by Struts, so you cannot use member variables in these classes. All variables setup need to be local and passed to the getJSON and getMapping methods via parameters.