|
|
Try with resources is a new feature in Java 7 which lets us write more elegant code by automatically closing resources like FileInputStream at the end of the try-block.
Old Try Catch Finally
Dealing with resources like InputStreams is painful when it comes to the try-catch-finally blocks. You need to declare the resources outside the try so that they are is accessible from finally, then you must initialize the variable to null and check for non-null when closing the resource in finally.
File file = new File("input.txt");
InputStream is = null;
try {
is = new FileInputStream(file);
// do something with this input stream
// ...
}
catch (FileNotFoundException ex) {
System.err.println("Missing file " + file.getAbsolutePath());
}
finally {
if (is != null) {
is.close();
}
}
Java 7: Try with resources
With Java 7, you can create one or more “resources” in the try statement. A “resources” is something that implements the java.lang.AutoCloseable interface. This resource would be automatically closed and the end of the try block.
File file = new File("input.txt");
try (InputStream is = new FileInputStream(file)) {
// do something with this input stream
// ...
}
catch (FileNotFoundException ex) {
System.err.println("Missing file " + file.getAbsolutePath());
}
Exception handling
If both the (explicit) try block and the (implicit) resource handling code throw an exception, then the try block exception is the one which will be thrown. The resource handling exception will be made available via the Throwable.getSupressed() method of the thrown exception. Throwable.getSupressed() is a new method added to the Throwable class since 1.7 specifically for this purpose. If there were no suppressed exceptions then this will return an empty array.
Reference
http://download.java.net/jdk7/docs/technotes/guides/language/try-with-resources.html
One of the new features added in Java 7 is the capability to switch on a String.
With Java 6, or less
String color = "red";
if (color.equals("red")) {
System.out.println("Color is Red");
} else if (color.equals("green")) {
System.out.println("Color is Green");
} else {
System.out.println("Color not found");
}
With Java 7:
String color = "red";
switch (color) {
case "red":
System.out.println("Color is Red");
break;
case "green":
System.out.println("Color is Green");
break;
default:
System.out.println("Color not found");
}
Conclusion
The switch statement when used with a String uses the equals() method to compare the given expression to each value in the case statement and is therefore case-sensitive and will throw a NullPointerException if the expression is null. It is a small but useful feature which not only helps us write more readable code but the compiler will likely generate more efficient bytecode as compared to the if-then-else statement.
While you can download the binaries for Java 7 for Windows and Linux from here, the instructions for setting up Java 7 for Mac OS X are a lot more tedious.
Here are the official instructions for Mac OS X: http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port
You can follow the instructions line by line and get Java 7 installed on your machine. However, these are the things that might go wrong:
Missing binaries in /bin
The installation expects a bunch of binaries to be present in /bin. However, on my Mac OS X, these binaries were present in /usr/bin/. My workaround was to create symlinks in the /bin directories to make the build happy.
cd /bin/
ln -s /usr/bin/sed
ln -s /usr/bin/grep
Repeat the above for each binary that is reported missing in /bin.
Missing jni.h
Make sure that the version of XCode is 3.2.5 or more. I had a 3.2.4 version and that didn’t work.
Building JTReg did not work due to a known bug
It is mentioned in the JTReg build documentation but easy to miss it. The following does not work due to a know bug:
make -C make
Instead try this:
make -C make build
Wrong installation directory in the official instructions
The official instructions ask you to do this:
mkdir -p ~/Library/Java/JavaVirtualMachines
cp -R build/macosx-universal/j2sdk-bundle/1.7.0.jdk ~/Library/Java/JavaVirtualMachines
That didn’t work for me. Here’s what worked for me:
mkdir -p /System/Library/Java/JavaVirtualMachines
cp -R build/macosx-universal/j2sdk-bundle/1.7.0.jdk /System/Library/Java/JavaVirtualMachines
Finally, setting up env vars
The easiest way to make confirm that Java 7 is successfully installed is:
/usr/libexec/java_home --version 1.7
The output of the above should be:
/System/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
Then type ‘java -version’ against the above installation
/System/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-root_2011_03_16_17_41-b00)
OpenJDK 64-Bit Server VM (build 21.0-b03, mixed mode)
Since I use Java 1.6 on the same machine, I saved the 1.7 path as follows:
export JAVA7_HOME=/System/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
This lets me conveniently switch to Java7, when I need to, and back:
export JAVA_HOME=$JAVA7_HOME
Switch back:
export JAVA_HOME=$JAVA6_HOME
Using Java7
Simplest way to use test Java7 is via command line
export JAVA_HOME=$JAVA7_HOME
export PATH=$JAVA_HOME/bin:$PATH
Compile
javac Test.java
Run
java Test
Overview
If you use JBoss Tools Plugin for Eclipse to deploy apps to JBoss 5.1 container and get a “SeamListener not found”, this post provides a simple workaround.
I deployed a webapp to JBoss 5.1 container from Eclipse using JBoss Tools plugin. The app failed to start with the following error:
19:01:14,762 WARN [JAXWSDeployerHookPreJSE] Cannot load servlet class: org.jboss.seam.servlet.SeamResourceServlet
19:01:14,787 INFO [TomcatDeployment] deploy, ctxPath=/hcf
19:01:15,143 ERROR [[/hcf]] Error configuring application listener of class org.jboss.seam.servlet.SeamListener
java.lang.ClassNotFoundException: org.jboss.seam.servlet.SeamListener
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:262)
at org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:256)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3859)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4393)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:310)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:142)
at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118)
at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
at $Proxy38.start(Unknown Source)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:286)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.system.ServiceController.doChange(ServiceController.java:688)
at org.jboss.system.ServiceController.start(ServiceController.java:460)
at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46)
at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
19:01:15,196 ERROR [[/hcf]] Skipped installing application listeners due to previous error(s)
19:01:15,196 ERROR [StandardContext] Error listenerStart
19:01:15,196 ERROR [StandardContext] Context [/hcf] startup failed due to previous errors
19:01:15,201 ERROR [AbstractKernelController] Error installing to Start: name=jboss.web.deployment:war=/hcf state=Create mode=Manual requiredState=Installed
org.jboss.deployers.spi.DeploymentException: URL file:/C:/software/jboss-5.1.0.GA/server/default/tmp/5c4o12w-udpgi-gf7dk40e-1-gf7dli4l-9o/hcf.war/ deployment failed
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:331)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:142)
at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118)
at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
at $Proxy38.start(Unknown Source)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:286)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.system.ServiceController.doChange(ServiceController.java:688)
at org.jboss.system.ServiceController.start(ServiceController.java:460)
at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46)
at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
19:01:15,209 ERROR [AbstractKernelController] Error installing to Real: name=vfsfile:/C:/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_Runtime_Server1286220891669/deploy/hcf.war/ state=PreReal mode=Manual requiredState=Real
org.jboss.deployers.spi.DeploymentException: URL file:/C:/software/jboss-5.1.0.GA/server/default/tmp/5c4o12w-udpgi-gf7dk40e-1-gf7dli4l-9o/hcf.war/ deployment failed
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:331)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:142)
at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118)
at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
at $Proxy38.start(Unknown Source)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:286)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.system.ServiceController.doChange(ServiceController.java:688)
at org.jboss.system.ServiceController.start(ServiceController.java:460)
at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99)
at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46)
at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
19:01:15,229 WARN [HDScanner] Failed to process changes
org.jboss.deployers.client.spi.IncompleteDeploymentException: Summary of incomplete deployments (SEE PREVIOUS ERRORS FOR DETAILS):
*** DEPLOYMENTS IN ERROR: Name -> Error
vfsfile:/C:/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_Runtime_Server1286220891669/deploy/hcf.war/ -> org.jboss.deployers.spi.DeploymentException: URL file:/C:/software/jboss-5.1.0.GA/server/default/tmp/5c4o12w-udpgi-gf7dk40e-1-gf7dli4l-9o/hcf.war/ deployment failed
DEPLOYMENTS IN ERROR:
Deployment "vfsfile:/C:/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_Runtime_Server1286220891669/deploy/hcf.war/" is in error due to the following reason(s): org.jboss.deployers.spi.DeploymentException: URL file:/C:/software/jboss-5.1.0.GA/server/default/tmp/5c4o12w-udpgi-gf7dk40e-1-gf7dli4l-9o/hcf.war/ deployment failed
at org.jboss.deployers.plugins.deployers.DeployersImpl.checkComplete(DeployersImpl.java:993)
at org.jboss.deployers.plugins.deployers.DeployersImpl.checkComplete(DeployersImpl.java:939)
at org.jboss.deployers.plugins.main.MainDeployerImpl.checkComplete(MainDeployerImpl.java:873)
at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.checkComplete(MainDeployerAdapter.java:128)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:369)
at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
This seemed to be a bug, as the above class is contained in the jboss-seam.jar, which I included in the classpath via the following maven snippet
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam</artifactId>
<version>2.2.0.GA</version>
</dependency>
I confirmed that the jar was not present in the deployed app, by going to the “Server” tab in eclipse and right-clicking on my app and “Explore”. The explore option launched a new window and listed the actual deployed app. I confirmed that the jboss-seam.jar was not present. Your deployment directory will be something like this:
C:\workspace\.metadata\.plugins\org.jboss.ide.eclipse.as.core\JBoss_5.1_Runtime_Server1286220891669\deploy\hcf.war
Upon Googling, I found that this is due to a known bug in JBoss Tools.
This issue has apparently been fixed in 3.2.0 M1.
Here “hcf” is the name of my app.
Workaround
By hit and trial, I found a simple workaround. After you deploy your webapp, simply copy the missing jar to the “lib” directory of the deployed app and restart Jboss.
Wrong location
You will find the file ‘jboss-seam-2.2.0.GA.jar’ in this directory.
C:\workspace\.metadata\.plugins\org.jboss.ide.eclipse.as.core\JBoss_5.1_Runtime_Server1286220891669\deploy\hcf.war
Correct location
C:\workspace\.metadata\.plugins\org.jboss.ide.eclipse.as.core\JBoss_5.1_Runtime_Server1286220891669\deploy\hcf.war\WEB-INF\lib
Move the seam jar from the wrong location to the correct location. Restart Jboss after moving the file, and the error should go away.
This articles describes how to secure a Java web application in JBoss using BASIC authentication.
Step1: Edit web.xml in your application
Edit the web.xml file in your webapp at the following location.
WEB-INF/web.xml
Edit your web.xml and put the following contents (generally towards the bottom of the file)
<web-app>
....
<security-constraint>
<web-resource-collection>
<web-resource-name>All resources</web-resource-name>
<description>Protects all resources</description>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>myrole</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>myrole</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Authorized access only.</realm-name>
</login-config>
</web-app>
This is a way of telling the container to restrict all URLs to any user with the role ‘myrole‘.
Step 2: Create jboss-web.xml in your application
Edit or create the jboss-web.xml file in your webapp at the following location.
WEB-INF/jboss-web.xml
Put the following contents:
<jboss-web>
<security-domain>java:/jaas/myappname</security-domain>
</jboss-web>
This tells JBoss to use application policy ‘myappname’ for this application.
Step 3: Create Application policy on JBoss server
We now need to define the application policy ‘myappname‘ on JBoss server.
Edit the login-config.xml file in the JBoss server directory at the following location.
jboss/server/default/conf/login-config.xml
Edit the contents of login-config.xml and add an application policy as follows:
<policy>
...
<!-- application policy for myappname -->
<application-policy name="myappname">
<authentication>
<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
<module-option name="usersProperties">props/users.properties</module-option>
<module-option name="rolesProperties">props/roles.properties</module-option>
</login-module>
</authentication>
</application-policy>
</policy>
This tells JBoss to user ‘UsersRolesLoginModule’ which uses property files to store users and roles.
Step 4: Create users on JBoss server
Now we create a new user with the role ‘myrole’.
Create a new User
Edit the users.properties file used by your application policy in Step 3.
jboss/server/default/conf/props/users.properties
Add a line to create a new user as follows.
myuser=mypassword
Roles
Finally, we assign the role ‘myrole’ to the user ‘myuser’. Edit the following file
Create a new role
Edit the roles.properties file used by your application policy in Step 3.
jboss/server/default/conf/props/roles.properties
Add a line to create a assign the role ‘myrole’ to ‘myuser’ as follows.
myuser=myrole
Test your settings
Restart the JBoss server and deploy your application. When you access your application, you should see a basic authentication popup.

If your setup is correct, you should be able to login using ‘myuser’ and ‘mypassword’ as defined in the Step 4.
Conclusion
This approach is equivalent to defining users, passwords and roles in tomcat-users.xml. While this is an easy approach and helps you get started, a real production web application should not store its passwords unencrypted on disk. We used BASIC authentication in this example. For production quality applications, you should use DIGEST, FORM or CLIENT-CERT.
I was trying to parse an XML file with Java JAXB. The XML file had the following header at the beginning of the file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE appspec [
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
<!ENTITY % HTMLspec PUBLIC
"-//W3C//ENTITIES Special for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
%HTMLlat1;
%HTMLspec;
]>
The program failed with the following error:
Server returned HTTP response code: 500 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
Full stacktrace:
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Could not read the xml, make sure that it is a valid xml and it validates against the schema
Server returned HTTP response code: 500 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
[INFO] ------------------------------------------------------------------------
[DEBUG] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Could not read the xml, make sure that it is a valid xml and it validates against the schema
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
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:284)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: Could not read the xml, make sure that it is a valid xml and it validates against the schema
at org.clickframes.mavenplugin.ClickframesGenPlugin.readProject(ClickframesGenPlugin.java:246)
at org.clickframes.mavenplugin.ClickframesGenPlugin.execute(ClickframesGenPlugin.java:126)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
... 17 more
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[java.io.IOException: Server returned HTTP response code: 500 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:197)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:174)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:225)
at org.clickframes.AppspecJaxbWrapper.readAppspecType(AppspecJaxbWrapper.java:53)
at org.clickframes.AppspecReader.readProject(AppspecReader.java:54)
at org.clickframes.mavenplugin.ClickframesGenPlugin.readProject(ClickframesGenPlugin.java:244)
... 20 more
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1313)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1252)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:722)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2069)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2032)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDInternalSubset(XMLDTDScannerImpl.java:377)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1141)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:977)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:195)
... 25 more
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34 seconds
[INFO] Finished at: Fri Oct 29 17:18:58 EDT 2010
[INFO] Final Memory: 17M/177M
[INFO] ------------------------------------------------------------------------
The program complained about not being able to download the file from www.w3.org. I tried to view the file in Firefox and was able to view it successfully. My hypothesis at that point was that w3.org is allowing Firefox but blocking Java. I confirmed that using wget and manually setting the User-Agent.
Using wget with User-Agent set to Firefox
You can set the user-agent using the -U option in wget
wget http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent -U "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10"
--11:24:08-- http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
Resolving www.w3.org... 128.30.52.37
Connecting to www.w3.org|128.30.52.37|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11775 (11K) [application/xml-external-parsed-entity]
Saving to: `xhtml-lat1.ent'
100%[======================================================================================================================>] 11,775 --.-K/s in 0.07s
11:24:08 (157 KB/s) - `xhtml-lat1.ent' saved [11775/11775]
Using wget with User-Agent set to Java
wget http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent -U "Java/1.6.0_20"
--11:24:17-- http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
Resolving www.w3.org... 128.30.52.37
Connecting to www.w3.org|128.30.52.37|:80... connected.
HTTP request sent, awaiting response... 500 Server Error
11:24:48 ERROR 500: Server Error.
The above verified that www.w3.org was blocking the request from Java.
Conclusion
W3.org blocks requests to certain resources originating from the Java program, identified by the User-Agent header ‘Java/1.6.0_20′. This is a known issue. The URLs have been deliberately blocked by w3.org due to ‘abusive’ use by Java programs. Read the full story here: W3C’s Excessive DTD Traffic.
The bottom line is that you, or your program, should download and cache a copy of this resource and not hit w3.org with a request to the same static resource over and over. Respect the Expiry date HTTP header.
Overview
One of the tricks to creating snappy and fast loading web pages is to set the correct ‘Expiry-date’ header on your web pages and static resources like images, CSS and Javascript files. By setting an expiration date in the future, you can tell the browser to cache the resource locally in the browser cache. This article discusses how to speed up your Java webapp by setting optimal expiration date to leverage browser caching.
An example of expiry date header is as follows:
Expires: Wed, 27 Oct 2010 19:02:24 EDT
The easiest way to set expiry date in Java webapps is via a servlet filter. Servlet filters are Java classes which extend the class javax.servlet.Filter. Servlet filters are an elegant way to intercept each request and do something useful, add a HTTP header in this case.
I wrote a Servlet filter which can be used to set the expiry date on any page in your webapp. You can use this servlet filter to set the expiry date header without writing any Java code in your project. You can also select which pages to set the expiry date and the age of the page via a properties file.
1. Download the code for expiration date filter and add it to your project
Download the file PageExpiryFilter.java and add it to your project.
2. Add a Servlet Filter to web.xml, and map it to all URLs
<filter>
<filter-name>PageExpiryFilter</filter-name>
<filter-class>com.vineetmanohar.web.PageExpiryFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PageExpiryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3. Create ‘expires.property’ file in src/main/resources
Create the following file:
src/main/resources/expires.properties
You can set expiry date for all or some paths in your webapp by simply creating entries in this file
The format for each line is:
Format:
Resource Path = freshness interval for this resource
Pattern:
<full regex of the resource> = <number><unit>
Valid values for Unit:
- m for minute
- h for hour
- d for day
- w for week
- M for month
Important
- Order in the properties file is important. The first rule which matches is applied and no more rules are checked.
- If no rules match, expiry date is not set.
- The path of the resource relative to the application root is matched against the regex. So if you app baseurl is http://foobar/somewebapp, the path for resource http://foobar/somewebapp/images/logo.png will be /images/logo.png.
Example 1:
^/css/.* = 30d
^/js/.* = 15d
^.*\.png$ = 2M
- The first line specifies, all content starting with /css expires in 30 days from current date.
- The second line specifies, all content starting with /js expires in 15 days from current date.
- The third line specifies, all content ending with .png expires in 15 days from current date.
- For those less familiar with regular expression, ^ denotes the beginning of the line and $ denotes the end of line. See full regex reference.
Example 2: For pages which don’t change a lot, you may want to set a smaller expiry date, says 4 hours. This is merely an example, you should examine the nature of your webapp before choosing the age of the page.
^/home/content/ = 4h
Example 3: Depending on how aggressive you want to be, you may want to set a default expiry date for all pages. This might not be suitable in all cases where pages change often and you want the browser to always load the latest page. Don’t use this if you don’t understand it completely.
.* = 1h
How to check Expiry Date header via a browser
 Viewing HTTP Headers for www.cnn.com in Firebug
There are many tools that let you check HTTP header values. My personal favorite is Firebug, which is a Firefox plugin. Once you have firebug open, go to the “Net” console, and view your page. You should see a GET or POST request as a row on the console. Expand that row, and go to the “Headers” tab. You should see all the headers, including the “Expires” headers if present.
The following screenshot is Firefug’s Net console displaying HTTP headers from www.cnn.com. Notice that the expiry date is for www.cnn.com home page is only 1 minute. This lets the browser cache the page for 1 minute, and re-fetch the page after 1 minute. While this is suitable for cnn.com where content might change every minute, you should decide the expiry date for your website depending on how often the content changes.
I highly recommend getting Firebug and looking at the expiry date of your webapp. Firebug also shows what gets downloaded each time you request a page and what is loaded from cache. This may help you determine your requirements, for example, if you notice a static resource (javascript file or css file) getting downloaded in each request, you might want to add an expiry date header for that resource.
Conclusion
Setting an expiration date in the future lets user’s browser cache pages locally and results in fast loading pages and increased end user satisfaction. The technique described in this article lets Java webapps very easily set expiration date without writing any Java code. However, keep in mind that setting a long expiration date might not be the right thing to do in many cases, e.g. where freshness of content is important, or there are security implications.
References
Overview
Some applications need to run periodic jobs in the background. On linux/unix systems, background processes can be run using the “cronjob” scheduling service. In Java web applications, you can add scheduling to any app in 4 simple steps using Spring and Quartz. This article outlines the steps needed for scheduling, with code snippets required for each step.
Step 1: web.xml
To initialize Spring in your webapp, add this snippet to your web.xml file. If you are already using Spring, you probably already have this in your web.xml.
<!-- Initialize Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Step 2: applicationContext.xml snippet
There are 3 concepts when configuring your scheduled jobs:
1) The Job: the java code that you want to run in the background periodically
2) A Trigger: a trigger adds scheduling information to your job. There are different types of triggers (e.g. SimpleTrigger, CronTrigger). They differ in the way you specify scheduling information. For example, CronTrigger takes a cronexpression, whereas SimpleTrigger takes a repeatInterval.
3) The Scheduler: this is the actual service which runs in the background and invokes ‘triggers’. You can register multiple triggers with this service.
Add this snippet to your spring xml file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- The 'Scheduler': quartz scheduler -->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- list of triggers registered with the scheduler -->
<property name="triggers">
<list>
<!-- Trigger1: JobExample using CronTrigger -->
<bean id="jobDetailTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<!-- job class -->
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailBean">
<!-- CHANGE THIS to the actual implementation class (see step 4) -->
<property name="jobClass" value="com.vineetmanohar.example.quartz.JobExample" />
</bean>
</property>
<!-- job schedule: every 5 minutes: CHANGE THIS -->
<property name="cronExpression" value="0 0/30 * * * ?" />
</bean>
<!-- Trigger2: JobExample2 using SimpleTrigger -->
<bean class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<bean>
<!-- CHANGE THIS to the actual implementation class (see step 4) -->
<property name="jobClass" value="com.vineetmanohar.example.quartz.JobExample2" />
</bean>
</property>
<!-- wait 4 minutes after startup -->
<property name="startDelay" value="240000" />
<!-- every 1 min (60 sec) -->
<property name="repeatInterval" value="60000" />
</bean>
</list>
</property>
</bean>
</beans>
Step 3: pom.xml snippet
If you are using maven, add this to your pom.xml to add spring and quartz dependency to your project.
<project>
<dependencies>
<dependency>
<groupId>org.opensymphony.quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</project>
Step 4: Java code snippet
Finally, write the actual implementation. Make sure that job class you specified in step 2 points to this file.
package com.vineetmanohar.example.quartz.JobExample;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class JobExample extends QuartzJobBean {
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("Job invoked at : " + new java.util.Date());
// TODO: implement the job here
}
}
Cron expression
The format of cron expression is <Seconds> <Minutes> <Hours> <Day-of-Month> <Month> <Day-of-Week> <Year (optional field)>. For example:
Every 30 minutes
0 0/30 * * * ?
See full reference documentation here.
 QR Code for "9780201750799"
Overview
Originally Barcodes were 1D representation of data using width and spacing of bars. Common bar code types are UPC barcodes which are seen on product packages. There are 2D barcodes as well (they are still called Barcodes even though they don’t use bars). A common example of 2D bar code is QR code (shown on right) which is commonly used by mobile phone apps. You can read history and more info about Barcodes on Wikipedia.
There is an open source Java library called ‘zxing’ (Zebra Crossing) which can read and write many differently types of bar codes formats. I tested zxing and it was able to read a barcode embedded in the middle of a 100 dpi grayscale busy text document!
This article demonstrates how to use zxing to read and write bar codes from a Java program.
Getting the library
It would be nice if the jars where hosted in a maven repo somewhere, but there is no plan to do that (see Issue 88). Since I could not find the binaries available for download, I decided to download the source code and build the binaries, which was actually quite easy.
The source code of the library is available on Google Code. At the time of writing, 1.6 is the latest version of zxing.
1. Download the release file ZXing-1.6.zip (which contains of mostly source files) from here.
2. Unzip the file in a local directory
3. You will need to build 2 jar files from the downloaded source: core.jar, javase.jar
Building core.jar
cd zxing-1.6/core
mvn install
This will install the jar in your local maven repo. Though not required, you can also deploy it to your company’s private repo by using mvn:deploy or by manually uploading it to your maven repository.
There is an ant script to build the jar as well.
Building javase.jar
Repeat the same procedure to get javase.jar
cd zxing-1.6/javase
mvn install
Including the libraries in your project
If you are using ant, add the core.jar and javase.jar to your project’s classpath.
If you are using maven, add the following to your pom.xml.
<dependencies>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>1.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>1.6-SNAPSHOT</version>
</dependency>
<dependencies>
Once you have the jars included in your project’s classpath, you are now ready to read and write barcodes from java!
Reading a Bar Code from Java
You can read the bar code by first loading the image as an input stream and then calling this utility method.
InputStream barCodeInputStream = new FileInputStream("file.jpg");
BufferedImage barCodeBufferedImage = ImageIO.read(barCodeInputStream);
LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
Result result = reader.decode(bitmap);
System.out.println("Barcode text is " + result.getText());
Writing a Bar Code from Java
You can encode a small text string as follows:
String text = "98376373783"; // this is the text that we want to encode
int width = 400;
int height = 300; // change the height and width as per your requirement
// (ImageIO.getWriterFormatNames() returns a list of supported formats)
String imageFormat = "png"; // could be "gif", "tiff", "jpeg"
BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, width, height);
MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.png")));
In the above example, the bar code for “97802017507991″ is written to the file “qrcode_97802017507991.png” (click to see the output).
JavaDocs and Documentation
The Javadocs are part of the downloaded zip file. You can find a list of supported bar code formats in the Javadocs. Open the following file to see the javadocs.
zxing-1.6/docs/javadoc/index.html
Reference
Overview
Sometimes it is useful to display the version of your web application, typically in the footer area of the web page. By displaying the version information, one can quickly determine which version of the app is running or users can use it for error reporting purposes. Displaying the version is also useful when there are frequent automated releases using the maven release plugin and it is hard to track which version is actually deployed on a server. Here’s an illustration of how version can be displayed in the footer.

This article describes how to display the version of your maven project in your web application.
Step 1: Create a View file to display the version
First we will create a view file which will display the version. The view file could be a JSP, HTML, XHTML, a Facelet or any format depending on your stack. In this example, we will create a JSP file which will print the version somewhere in the page. However, instead of the hardcoding an actual version, we put a special token ‘PROJECT_VERSION’. We don’t want to hard code the version information as it will change from release to release. The special token will be replaced with actual maven project version when the app is packaged.
Create the following jsp.
src/main/webapp/version.jsp
Here’s a simple file which displays the version information.
<html>
<body>Project version is <i>PROJECT_VERSION</i></body>
</html>
Step 2: Add snippet to pom.xml
The maven replacer plugin is a simple and useful plugin which can replaces tokens in file of your choice. Add the following snippet of code to your pom.xml. (Note: you can also use the maven resources plugin’s filter feature to accomplish this).
<project>
<build>
<plugins>
<!-- replace version in file -->
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<!-- the replace should happen before the app is packaged -->
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<!-- replace the token in this file -->
<include>target/myproject/version.jsp</include>
</includes>
<regex>false</regex>
<!-- the name of the token to replace -->
<token>PROJECT_VERSION</token>
<!-- replace it with the maven project version -->
<value>${project.version}</value>
</configuration>
</plugin>
</plugins>
</build>
</project>
To test the above setup, you can run the following command:
mvn prepare-package
Navigate to the following file.
target/myproject/version.jsp
The contents of this file will look something like this (assuming that your project version is 1.0-SNAPSHOT):
<html>
<body>Project version is <i>1.0-SNAPSHOT</i></body>
</html>
When your application ships, the version.jsp file will always have the correct version. You can see the version by invoking the version.jsp page.
http://localhost:8080/myproject/version.jsp
Note:
- Your view file does not have to be a JSP, it can be any a view file suitable to your stack. It could be part of your footer which could be included at the bottom in each page.
- The special token can be changed from PROJECT_VERSION to another value of your choice, just change it in the view file as well as the pom.xml
- Instead of having the version contained in a view file, you could have the version in a properties file or a message bundle and then display a message from the message bundle on the view
- Update – you can also accomplish the replacement using the filtering feature of maven resource plugin
References
|
|