November 8th, 2011
8:02 pm
iMedia Linux– configuration/application install issues

Posted under Linux
Tags , , , , , , ,

This post brings together a number of past issues which I have not posted previously, discovered while setting up and using iMedia embedded Linux on my diskless LinITX Jupiter test box.

A zip of all the customised scripts and various config files (such as the infamous xorg.conf) are in the repository.

Shell Script Usage

1/ The startup scripts for applications and drivers etc. are in /etc/rcS.d/. You just add scripts to that and they are automatically run. They are all run by /etc/rcS in alpha order. They are grouped by a prefix of M05, M10, M20, M30 etc. – this seems just to be an arbitrary grouping that determines the order for dependencies etc. Note that all of rcS.d/ is run at run level 3 as set in /etc/inittab

The general order of startup is therefore (see /etc/inittab):-

  • /etc/rc.init runs, and calls rc.sysinit directly
  • /etc/rc.sysinit iterates init.d and runs everything in it. The order is partly determined by an initial grouping number – note the first to run is 00createvar which creates the /var tree on startup (see later)
  • /etc/rcS runs as above, iterating /etc/rcS.d/

2/ /usr/local/bin/ has the extra shared shell scripts – rlog, rlog-leafpad, sx (start X), sxr (start X as root), plus start/stop scripts for Tomcat and Glassfish.

In Thunar, you can add file associations for scripts by right clicking in the file and selecting open with other application – for each app you can add a custom launch command below. (I added rlog and rlog-leafpad). If you add an incorrect one (I added beaver by mistake) Thunar may not let you remove it from the list. Just edit ~/.local/share/applications/defaults.list and remove it from there. Note that /usr/local/bin/ is already on the path so all the script in it are visible – good place to put other global scripts.

Note that you can add scripts to e.g. a program launcher on the top panel bar – right click and create a program launcher, then add items to it – useful for scripts which run without parameters (unlike the rlog and rlog-leafpad above which act on files and therefore are Thunar’s context menu for the files they operate on). When adding a script as an item to a program launcher, the ‘startup notification’ just gives a wait cursor while the script is running (useful). Running in an explicit terminal window is WEIRD – for example for glassfish I set the middle icon on the RHS pane to “terminal”, and set the command to be “aterm -e start-glassfish”. I did not tick “Run in Terminal” as this did not work however!

Logging under iMedia Linux

1/ Logs are stored under the /var tree which is recreated at startup each time see above, so log files are purged as we are running on a small flash based distro. Therefore, Tomcat and Glassfish for example are set to use sym links to link their log directories from their normal install directories to be under /var/log/. There is some trickery to this – for Glassfish I make sure that the *normal* log folder is not present (renaming it with a date/time stamp if required) else the sym link is set up wrongly.

2/ Some logs (but by no means all) in /var/logs/ are circular buffers handled by emlog  – see here for details. They show in Thunar as ‘character type devices’ and  need copying to be visible – /usr/local/bin/rlog does this using nbcat as per the emlog site. I also added /usr/local/bin/rlog-leafpad which does the copy and fires up leafpad on the result. Note that as the emlog site states, you cannot list such a log when active using cat as a non blocking read is required – hence the need for nbcat as used by rlog and rlog-leafpad.

Installing new Applications

1/ Installing new apps is a pain, as rpm installs don’t appear to be supported etc. I tried installing various zipped tarballs of VNC/RDP alternatives for remote desktop but they all needed dependant libraries I did not have, so I had to give up. I think you can build from source to add things but did not go that far! The apps I did install successfully – java 1.6.0_29, tomcat 6.0.29 and Glassfish 3.0.1 – was all installed in folders under /opt as this appeared to be the correct place. Note that for Tomcat, I placed the config files under /etc/apache-tomcat-6.0.20/conf/ and sym-linked them from the ‘expected’ place, /opt/apache-tomcat-6.0.20/opt/, as this appeared to be correct protocol – other apps placed their config under /etc/ and linked to it from their install directory under /opt/. However I did not go to the trouble of doing this for Glassfish – it would be possible (I did do it for the log directory) but the directory structure is more complex.

2/ I did have success with Java – I just ran the .bin install kit of the latest Linux version of the sun Java SE (jdk6u29), and it all unzipped properly and ran fine. Thankfully there were no library problems – probably because there had already been an earlier working jdk6 already installed by default. I added a shell script /etc/profile.d/java-jdk1.6.0_29.sh which created the JAVA_HOME and added the bin directory to the path, but note that this did not work for init time shell scripts for either Tomcat or Glassfish, so their startup scripts had to add their own definitions to work.

3/ I successfully installed Glassfish 3.0.1 (from the zip kit download). To get it to work I had to upgrade Java as above as I got errors otherwise, and the old jdk was below the minimum certified version. However, it worked fine after upgrading java. Note that to stop it checking for updates on startup I just renamed /opt/glassfish-3.0.1-web/glassfish/modules/console-updatecenter-plugin.jar by adding “.disabled” on the end. You can achieve the same thing using the updatetool, but this failed to install properly due to a python error/dependency. I also removed the default jsf-api.jar and jsf-impl.jar from the same folder as above, and added the Mojarra 2.0.4 FCS jars to the folder instead, as my apps needed this version. Note that this also speeds up the startup of the Glassfish admin tool. See my notes here about clearing the osgi cache if you do this.

4/ For Tomcat and Glassfish I separated out the log directory creation from the actual startup, using separate scripts. The log creation is always run, and so sits under /etc/rcS.d/, and the auto startup is optional and may sit under /etc/rcS.disabled/ as a placeholder if it is not autostarted. However, as the log directories under /var/ are always setup, you can then manually start them if desired and they will still work. This is done with the scripts in /usr/local/bin/start-glassfish/stop-glassfish/start-tomcat/stop-tomcat. As this directory is on the path, the scripts can be directly run from a terminal window OR from a remote SSH window BUT you would need to be logged in as root to do it.

Graphical Remote Desktop

Re remote desktop, it is in theory possible to use a windows based X server and connect in that way. To do this, you need to run an X display manager on the Linux box to handle the xdmcp protocol etc. imedia linux does have /usr/bin/xdm which is an old display manager. I did manage to run it from the initial login prompt before typing startx, just by typing xdm, and it popped a login screen. However it would not connect to xfce. It recognised a valid login and tried to do something, failed, and redisplayed itself. An invalid login gave a login failure. I also managed to run the launcher from XMING under windows, and got as far as connecting to xdm. to do this I edited /etc/X11/xdm/Xaccess to enable the “*” entry to allow all comers. I also experimented with editing /etc/X11/xdm/xdm-config and set DisplayManager*authorize to false, and tried commenting out the last line as follows :-

! SECURITY: do not listen for XDMCP or Chooser requests
! Comment out this line if you want to manage X terminals with xdm
!DisplayManager.requestPort:    0

I managed to get XMING to display the same xdm login screen that I got locally, which was a good start – I knew I had a connection working. However, I realised in the end that xfce does not appear to be using a display manager – it simplifies things and bypasses it, and to set up xdm to link properly to xfce and to work remotely looked like loads of setting up with no instructions on how to do it properly.

I therefore sadly gave up on this and admitted defeat on installing any kind of graphical remote desktop!

Samba

I got the samba server to share folders successfully – I added the shares in /etc/samba/smb.conf. Security was set to user (security = user). I tried setting “valid users=” to a list of users, to allow restriction of users e.g. to glassfish/tomcat log folders, but could not get this to work, so I left it out.

Note that I did need to use “smbpasswd -a username” to add an existing linux user to the samba user list, and give it a password. You need to run as root to do this, or it merely allows you to change your own password. smbusers allows you to map external users (used by windows clients) to linux users – see here. Note that you don’t need to do this – you can just use the linux names. Note also that when adding/setting passwords with smbpasswd, you *always* use the Linux name, not the samba alias. Some other useful links for Samba follow:-

Ftp, Telnet and SSH

1/ ftp is enabled by default via vsftp. The config file is in /etc/vsftpd/vsftpd.conf. The default settings are pretty sensible in opening it up for use in a secur local lan. ftp works via all the local linux accounts including root. The log is in /vat/log/vsftpd.log.

2/ Telnet works but does not allow root access (presumably as too insecure). utelnetd is the daemon but there is no documentation for it on the net I could find. SSH works fine via the sshd and allows root access, but could not find any config files or logging for it, although it is documented on the net – the man pages are here, however the config files mentioned for the daemon do not appear to be present under imedia Linux. No problem, it is set up fine for LAN use and works well from putty in ssh mode.

No Comments »

October 4th, 2011
12:10 pm
Glassfish 3.0.1–Slow login due to checking for updates

Posted under Glassfish
Tags , ,

I did a new install of GF 3.0.1 on a laptop, and elected not to install the update tool as this was a fixed demo environment.

I found that when connecting to Glassfish admin, login was very slow, easily taking a minute or more longer than normal. After login, the main screen displayed a count of available updates at the top left, which I had not seen in the past. This looked suspicious and I wondered if the slowness was due to checking for available updates.

It turned out that this was indeed the case. This post discusses the issue and various workarounds, including disabling network access for Glassfish and removing a jar – neither of which I particularly liked. The post indicated that you could set preferences in the update tool, but as I had not installed it I was stuck.

I then tried reinstalling GF from scratch, this time selecting the update tool as well during install, but not selecting the check box for ‘checking for updates’. After doing this, I discovered that the problem was no longer present – login was quicker and the count of available updates was not displayed. It was also possible to use the update tool to configure preferences, but in my case automatic update checking was off anyway.

The solution to this issue, somewhat paradoxically, is therefore, if you want a fixed installation with no update checking, make sure you still select the update tool when installing, but do not enable checking for updates. This solves the problem, and also allows you to configure update preferences later if you wish.

No Comments »

April 2nd, 2011
5:50 pm
Updating components such as JSF, JPA in Glassfish

Posted under Glassfish
Tags , , , , ,

Update 04/10/2011

An essential step was omitted below, which is to clear out the OSGI cache. If you do not do this, and for example manually update Mojarra, the old version will still be loaded from the OSGI cache so your update will not take effect (and probably leave you wondering where glassfish can possibly still be getting the old version from!)

The simple solution is to ensure that you clear the OSGI cache after an update. The cache will be automatically rebuilt by Glassfish.

Simply delete all files in the  <glassfish-root>/glassfish/domains/domain1/osgi-cache/ folder. (Typically this just has a felix  subfolder to be deleted).

This solves the problem.

 

Original

Glassfish has its updatetool which automatically lists and installs updates from known repositories. You can add to the list of repositories, but they have to be of the type that Glassfish will accept – it will not install from any old download site.

When I wanted to update Mojarra in GF 3.0.1 from 2.0.2 FCS to 2.0.4 FCS with the updatetool, I could not find an update site with that version on.

The alternative (which I did) is to update manually – in this case to stop Glassfish and copy the jsf-api.jar and jsf-impl.jar into the <glassfish-root>\glassfish\modules directory, then restart. The only issue with this is that the new version will not be correctly listed in the installed components under the update tool or in the glassfish administration if you do it manually. However, you can verify that the correct version is running by starting glassfish and one of your web apps running in it, then look in the log for Mojarra and you will see that Mojarra logs its version when it loads. (Be careful if using Notepad++ – I found that its search was unreliable when searching backwards in the log for Mojarra, and it missed the relevant matches.

This can also be done for JPA/Eclipselink. However, the issue with this is that in the update tool it is listed with the name Glassfish JPA, with a different version number to the one used for Eclipselink. It is therefore not possible to work out which version of Eclipselink you are upgrading to. Some of the forums suggest just copying in a later set of Eclipselink OSGI jars but this just does not feel right for OSGI!

The only think I can be certain of is the installed version of Eclipselink with a base version of Glassfish, as this is documented as part of the Glassfish release.

At present I am sticking with the Eclipselink 2.0.2 version that ships with Glassfish, as I have not had any problems with this.

No Comments »

March 7th, 2011
10:23 am
JUnit testing EJBs with Eclipse / Glassfish 3.0.1 – EJB 3.1 embedded container

Posted under Glassfish
Tags , , , , , ,

Update – Controlling Logging with the JUnit Eclipse Plugin

Controlling logging with the Eclipse JUnit plugin is not obvious and not documented. Even a trawl of the net did not find an answer even though the question was asked on some forums. Fortunately, it is straightforward once you know. By default, JUnit under Eclipse just logs at INFO level. It uses java.util.logging by default, and therefore the way to contol it is as follows :-

1/ Make a local copy of logging.properties from the one under your JAVA_HOME/jre/lib directory – in my case I placed it under <eclipse project>/test, which was the top level test folder.

2/ Add the following VM argument to the run configuration used for JUnit testing of your project (see under Run/Run Configurations):-

-Djava.util.logging.config.file=${workspace_loc:YourEclipseProject}\\test\\logging.properties

The {} construct allows you to conveniently specify the file system path to your Eclipse project. Note that the path delimiters for Windows are escaped as per usual.

3/ Then edit the logging.properties as desired. The comments in the file are pretty comprehensive. Note that the console logger has its own limit on logging level even if you specify a more detailed level for your own package. For JUnit testing, I prefer to disable the console logger and just log to a file, as then I can just refer to the JUnit pane without it being interrupted with the scrolling console log, as a scrolling log goes against the JUnit principle of automated testing anyway. When specifying your own logging file you can use a path relative to the top level project directory, and %h in the name is your user home directory, and %u is used as a version number when successive log files are created with the same name. The following shows my sample logging.properties:-

############################################################
#      JUnit Testing Logging Configuration File – S.E. Woodley
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property. 
# For example java -Djava.util.logging.config.file=myfile
############################################################

############################################################
#      Global properties
############################################################

# "handlers" specifies a comma separated list of log Handler
# classes.  These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
#handlers= java.util.logging.ConsoleHandler

# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
#
#S.E. Woodley remove the console handler for JUnit testing.
handlers= java.util.logging.FileHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers.  For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

# default file output is in user’s home directory.
#java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.pattern = test\\JUnitTest%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
#java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.xyz.foo.level = SEVERE
uk.co.salientsoft.level=INFO

Using Exit Codes when running Scripts etc. for Test setup

1/ In my case I needed to run a SqlPlus script to populate a test database as part of the JUnit test setup. With SqlPlus, it is possible for a script to return an exit code which indicates success, or whether there was an SQL or operating system error such as an error finding a called script. This post here indicates how this can be done. This is obviously highly desirable for JUnit testing as successful script execution can then correctly affect the test outcome via an assert. My ScriptRunner class, mentioned below, returns the exit code from SqlPlus.

2/ I used my ScriptRunner utility class which allows simple property file based setup for running external OS programs such as SqlPlus, and which acts as a wrapper to the standard Java ProcessBuilder class. ScriptRunner will be found in the repository. The sample code at the end of this post has been modified to show the use of ScriptRunner with exit code assert handling, in the @BeforeClass method.

Original Post

The new embedded container in Java EE 6 is a good choice for unit testing of EJBs. It allows standalone testing outside of a full container, and supports CDI and CDI injected beans in EJBs, including the injection of POJOs into EJBs. The following steps explain how to set it up, as their are a  few gotchas for the unwary. There are other approaches to this – in particular there is a distinction between using the embedded API and an embedded container. However, the following approach was commonly used by a number of sites, is straightforward, and ticked all my boxes for JUnit testing of EJBs. A code sample is at the foot of this post.

1/ Add the following embedded container shell jar to your classpath. Failure to do this results in the following error :-

        javax.ejb.EJBException: No EJBContainer provider available: no provider names had been found.

I defined an Eclipse User Library for it:-

        <install-dir>\glassfish\lib\embedded\glassfish-embedded-static-shell.jar

Note that when doing this, the User Library must point to the actual jar in the glassfish instance you are using. You cannot just copy the library to another location and point to it, or you will continue to get the above provider names error. The above jar is a ‘shell jar’ explicitly designed to link an embedded container to an existing glassfish installation. The embedded container uses the shell jar location to detect the glassfish instance to use to obtain the necessary run configuration. For example, if your EJBs make calls to JPA and use a data source named in persistence.xml, then the embedded container will use the data source defined in the glassfish instance you are pointing at.

Some posts talk about having to use the default in-memory data source name when testing, but this is probably due to a difference in the way the embedded container is being configured and used. For example, there are other embedded jars you can use which are not designed to tie in to an existing glassfish installation. In my case this was not necessary and my existing Oracle data source was automatically discovered and used.

2/ Next, add a second copy of beans.xml in src/META-INF (alongside persistence.xml and orm.xml). There is a gotcha here – the full container deployment of a war file needs to see it in WEB_INF, but this will not work for the embedded container. I was unable to find a single location that would satisfy both, and I tried passing properties to the embedded container to get it to see the beans.xml in WEB_INF, but to no avail. Note that if you do not add the second copy as above, you may find that some injection works, e.g. for EJBs into other EJBs, but in my situation I sometimes had POJOs (such as the Apache Base64 encoder) injected into EJBs, and for this to work, you have to get this step right. In the end, I also added a unit test to check that POJO injection was working, with a warning to check beans.xml  if the test failed.

3/ Eclipse (helios in my case) has good support for JUnit 4, and tests and test suites can be run directly by right clicking and selecting Run as JUnit Test or Debug as JUnit test. It also has a wizard to allow creation and maintenance of test suites, but sadly this did not work due to a known bug. The code below illustrates how to create a suite using annotations (you can also do it with code). Creating stubs for unit tests is also easy via right click in the explorer and selecting New JUnit test, and selecting the class to test etc. If JUnit 4 is not already present on your build path, Eclipse will prompt you to add it.

4/ When creating the tests in Eclipse, I added a new source folder just for the tests, as test/src  to keep the tests separate from deployed code. Also, in the build path dialog (right click the project and select Build Path/Configure Build Path), on the source tab I ticked allow output folders for source folders,and added test/classes as the output folder for the tests. Note that after doing this, I visited the deployment assembly property page (right click the project in the explorer, select properties, and select Deployment Assembly in the left hand pane), and ensured that the /test directory was removed to ensure that the test classes would not be deployed in the war file.

5/ When running, I did get a couple of exceptions in the log, from the internal setting up of the embedded container. These did not prevent it from starting or working correctly, and all my unit tests ran fine. They are in fact known bugs (which can be ignored) which have been raised on the Glassfish Jira issue log here and here. Here is a sample of the error traces:-

17-Dec-2011 23:18:09 org.glassfish.flashlight.impl.provider.FlashlightProbeProviderFactory processXMLProbeProviders
SEVERE: MNTG0301:Cannot process XML ProbeProvider, xml = META-INF/mojarra-jsf-api-probe-provider.xml
java.lang.IllegalStateException: Provider already mapped glassfish:jsf:faces-servlet
    at org.glassfish.flashlight.impl.core.ProbeProviderRegistry.registerProbeProvider(ProbeProviderRegistry.java:96)
    at org.glassfish.flashlight.impl.provider.FlashlightProbeProviderFactory.registerProvider(FlashlightProbeProviderFactory.java:521)
    at org.glassfish.flashlight.impl.provider.FlashlightProbeProviderFactory.processXMLProbeProviders(FlashlightProbeProviderFactory.java:360)
    at org.glassfish.admin.monitor.MonitoringBootstrap.processProbeProviderXML(MonitoringBootstrap.java:407)
    at org.glassfish.admin.monitor.MonitoringBootstrap.addProvider(MonitoringBootstrap.java:282)
    at org.glassfish.admin.monitor.MonitoringBootstrap.verifyModule(MonitoringBootstrap.java:219)
    at org.glassfish.admin.monitor.MonitoringBootstrap.discoverProbeProviders(MonitoringBootstrap.java:165)
    at org.glassfish.admin.monitor.MonitoringBootstrap.enableMonitoringForProbeProviders(MonitoringBootstrap.java:539)
    at org.glassfish.admin.monitor.MonitoringBootstrap.postConstruct(MonitoringBootstrap.java:153)
    at com.sun.hk2.component.AbstractWombImpl.inject(AbstractWombImpl.java:174)
    at com.sun.hk2.component.ConstructorWomb$1.run(ConstructorWomb.java:87)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.hk2.component.ConstructorWomb.initialize(ConstructorWomb.java:84)
    at com.sun.hk2.component.AbstractWombImpl.get(AbstractWombImpl.java:77)
    at com.sun.hk2.component.SingletonInhabitant.get(SingletonInhabitant.java:58)
    at com.sun.hk2.component.LazyInhabitant.get(LazyInhabitant.java:107)
    at com.sun.hk2.component.AbstractInhabitantImpl.get(AbstractInhabitantImpl.java:60)
    at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:212)
    at com.sun.enterprise.v3.server.AppServerStartup.start(AppServerStartup.java:128)
    at com.sun.enterprise.module.bootstrap.Main.launch(Main.java:457)
    at com.sun.enterprise.module.bootstrap.Main.launch(Main.java:401)
    at com.sun.enterprise.module.bootstrap.Main.launch(Main.java:310)
    at com.sun.enterprise.module.bootstrap.Main.launch(Main.java:303)
    at com.sun.enterprise.glassfish.bootstrap.ASEmbedded.run(ASEmbedded.java:101)
    at com.sun.enterprise.glassfish.bootstrap.AbstractMain.start(AbstractMain.java:78)
    at org.glassfish.api.embedded.Server.<init>(Server.java:288)
    at org.glassfish.api.embedded.Server.<init>(Server.java:61)
    at org.glassfish.api.embedded.Server$Builder.build(Server.java:158)
    at org.glassfish.api.embedded.Server$Builder.build(Server.java:140)
    at org.glassfish.ejb.embedded.EJBContainerProviderImpl.init(EJBContainerProviderImpl.java:154)
    at org.glassfish.ejb.embedded.EJBContainerProviderImpl.createEJBContainer(EJBContainerProviderImpl.java:114)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:102)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)
    at uk.co.salientsoft.cheepcheep.service.impl.DomainServiceImplTest.setUpBeforeClass(DomainServiceImplTest.java:44)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

(then further down in the log…)

WARNING: Exception while performing resource-adapter’s security permission check :
java.io.FileNotFoundException: E:\Java\Dev\Helios-SR2\Workspaces\CheepCheep\TraderUI\gfembed880784300432477021tmp\config\server.policy (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileReader.<init>(FileReader.java:55)
    at com.sun.enterprise.connectors.service.ConnectorConfigurationParserServiceImpl.getFileContent(ConnectorConfigurationParserServiceImpl.java:133)
    at com.sun.enterprise.connectors.service.ConnectorConfigurationParserServiceImpl.getSecurityPermissionSpec(ConnectorConfigurationParserServiceImpl.java:92)
    at com.sun.enterprise.connectors.ConnectorRuntime.getSecurityPermissionSpec(ConnectorRuntime.java:495)
    at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:239)
    at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:338)
    at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:327)
    at com.sun.enterprise.connectors.service.ConnectorService.loadDeferredResourceAdapter(ConnectorService.java:164)
    at com.sun.enterprise.connectors.service.ConnectorService.loadResourcesAndItsRar(ConnectorService.java:133)
    at com.sun.enterprise.connectors.service.ConnectorService.checkAndLoadPool(ConnectorService.java:307)
    at com.sun.enterprise.connectors.service.ConnectorResourceAdminServiceImpl.createConnectorResource(ConnectorResourceAdminServiceImpl.java:91)
    at com.sun.enterprise.connectors.ConnectorRuntime.createConnectorResource(ConnectorRuntime.java:266)
    at com.sun.enterprise.resource.deployer.JdbcResourceDeployer.deployResource(JdbcResourceDeployer.java:107)
    at org.glassfish.javaee.services.ResourceProxy.create(ResourceProxy.java:84)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:432)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.enterprise.connectors.service.ConnectorResourceAdminServiceImpl.lookup(ConnectorResourceAdminServiceImpl.java:203)
    at com.sun.enterprise.connectors.ConnectorRuntime.lookupPMResource(ConnectorRuntime.java:429)
    at org.glassfish.persistence.jpa.JPADeployer$ProviderContainerContractInfoImpl.lookupDataSource(JPADeployer.java:228)
    at org.glassfish.persistence.jpa.PersistenceUnitInfoImpl.<init>(PersistenceUnitInfoImpl.java:108)
    at org.glassfish.persistence.jpa.PersistenceUnitLoader.loadPU(PersistenceUnitLoader.java:130)
    at org.glassfish.persistence.jpa.PersistenceUnitLoader.<init>(PersistenceUnitLoader.java:96)
    at org.glassfish.persistence.jpa.JPADeployer.prepare(JPADeployer.java:121)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:644)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:296)
    at org.glassfish.kernel.embedded.EmbeddedDeployerImpl.deploy(EmbeddedDeployerImpl.java:214)
    at org.glassfish.kernel.embedded.EmbeddedDeployerImpl.deploy(EmbeddedDeployerImpl.java:144)
    at org.glassfish.ejb.embedded.EJBContainerImpl.deploy(EJBContainerImpl.java:128)
    at org.glassfish.ejb.embedded.EJBContainerProviderImpl.createEJBContainer(EJBContainerProviderImpl.java:120)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:102)
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)
    at uk.co.salientsoft.cheepcheep.service.impl.DomainServiceImplTest.setUpBeforeClass(DomainServiceImplTest.java:44)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
17-Dec-2011 23:18:17 com.sun.ejb.containers.BaseContainer initializeHome

6/ In my case, my project used JPA 2 and Eclipselink, with Oracle XE. Happily I found that as long as I followed the above steps properly, everything ran fine with no messing about and no need for special setup or property passing to the embedded container. It feels a bit like ‘smoke and mirrors’ when you first see it and you wonder how everything is discovered automatically, but once you understand the point about using the embedded shell jar in the actual glassfish instance it all becomes clear. Note that it does not matter whether or not your project is currently deployed to the target glassfish instance – all that matters is that the necessary configuration such as data sources are present and correct.

7/ Note that whilst I did manage to get CDI injection of POJOS into an EJB working as in 2/, I was not able to directly instantiate a POJO from the container context, so for example I could not test a POJO which then called an EJB. It is of course vital that the initial bean under test is created from the container context or it will not run in the container. A number of posts on the net like this one here discuss trying to obtain a BeanManager using ctx.lookup("java:comp/BeanManager") which should work for Java EE 6, in order to use the BeanManager to obtain CDI bean reference from the embedded container context. However, all the posts I found failed to find a solution. This Jira post may indicate the fundamental problem.

I did attempt a workaround – all CDI beans (including EJBs) can obtain a BeanManager reference by using e.g. @Inject private BeanManager beanManager. I therefore tried creating a BeanManagerLocator EJB whose sole job was to inject the BeanManager and return it via a getter. This did allow me to obtain a valid BeanManager. I then tried to get a bean reference to my CDI model bean (a dependent bean used to decouple JSF controllers from the service layer) as follows :-

BeanManagerLocator beanManagerLocator = (BeanManagerLocator) ctx.lookup("java:global/classes/BeanManagerLocator");
BeanManager beanManager = beanManagerLocator.getBeanManager();

Bean<?> modelBean = beanManager.getBeans(Model.class).iterator().next();
CreationalContext<?> cc = beanManager.createCreationalContext(modelBean);
Model model = (Model)beanManager.getReference(modelBean, Model.class, cc)

Unfortunately, the final statement which actually gets the bean reference failed an error, at which point I gave up. Clearly some deeper magic is needed to create the CDI bean outside of the container. It might be possible to achieve this by bootstrapping CDI separately outside the container, and this is certainly possible in Java SE. However, there is then the issue of coupling the CDI environment outside the container to the one inside, so that the whole test environment is integrated like the normal one. I decided that all this was a bridge too far. Here is the error mentioned at the top of this paragraph:-

java.lang.IllegalStateException: No valid EE environment for injection of uk.co.salientsoft.test.view.ModelImpl

 

Whilst researching this, I found the following links useful:-

  • This post uses Glassfish 3.1 and maven, and sets up a custom glassfish configuration on the classpath using domain.xml. Interesting, but I prefer to tie to the configuration of an actual development instance as my configuration is then all centralised, in step, and can be maintained by the glassfish admin tool.
  • This post by Adam Bien is interesting but does not mention how to tie the configuration using the shell jar, and what to do about the above “no provider names had been found” error.
  • This post discusses the concept from a CDI perspective
  • Oracle documentation about the embedded container and embedded API may be found here and here

 

Code Example

AllTests.java

@RunWith(Suite.class)
@Suite.SuiteClasses({
    DomainServiceImplTest.class,
})
public class AllTests {}

DomainServiceImplTest.java

public class DomainServiceImplTest {
    private static EJBContainer ejbC;
    private static DomainServiceLocal domainService;
    
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {

        /* Populate the database with the correct test data */
        ScriptRunner scriptRunner = new ScriptRunner();
        int exitCode = scriptRunner.run("test\\PopulateTestDatabase");

        assertTrue (String.format("SqlPlus script exit code was: %s, should be 0", exitCode), exitCode == 0);

        ejbC = EJBContainer.createEJBContainer();
        Context ctx = ejbC.getContext();
        
       /*
         * List the available ejbs for the container – useful when debugging the test environment
         * The empty name string lists all the top level binding categories
         * java:global/classes lists all the ejbs for the embedded container
         */
        NamingEnumeration<Binding> ne = ctx.listBindings("");       
        while(ne.hasMore()) {
            Binding b = (Binding) ne.next();
            System.out.println(b.getName() + " – " + b.getObject());
        }
        ne = ctx.listBindings("java:global/classes");       
        while(ne.hasMore()) {
            Binding b = (Binding) ne.next();
            System.out.println(b.getName() + " – " + b.getObject());
        }
        domainService = (DomainServiceLocal) ctx.lookup("java:global/classes/DomainServiceImpl");   
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {

         // Close the container when done to save resources  
        ejbC.close();       
    }

    @Test public void testCDIPojoInjection() throws Exception {
        assertFalse("CDI POJO injection – embedded ejb container requires 2nd beans.xml in src/META_INF for this to work",
                                domainService.getTreeSearchBuilder() == null);       
    }
    @Test public void testFetchTaxonomiesNotNull() throws Exception {
        List<Taxonomy> taxonomies = domainService.fetchTaxonomies(true);       
        assertFalse("Taxonomies returned should not be null", taxonomies == null);
    }
    @Test public void testFetchTaxonomiesCount() throws Exception {
        List<Taxonomy> taxonomies = domainService.fetchTaxonomies(true);       
        assertTrue("Taxonomies returned should have count of 1", taxonomies.size() == 1);       
    }
    @Test public void testFetchTaxonomiesDefault() throws Exception {
        List<Taxonomy> taxonomies = domainService.fetchTaxonomies(true);       
        assertTrue("Taxonomy returned should be the default", taxonomies.get(0).isDefaultTaxonomy());       
    }
}

PopulateTestDatabase.properties

#ScriptRunner property file to populate test data via SqlPlus
scr.include=sqlplus
scr.name=Populate Test Data

scr.directory=test\\database
scr.param.user=testdb4
scr.param.password=password4
scr.param.database=xe
scr.param.scriptfile=PopulateAll.sql
scr.log.file=..\\PopulateTestDatabase.log
scr.log.append=false
scr.log.console=false

sqlplus.properties  (this property file is standard to ScriptRunner and is run directly from within ScriptRunner.jar)

# ScriptRunner definition for Oracle SqlPlus under Windows

# Give the script a name (this can be overridden by a calling script)
scr.name=SqlPlus

# Define the command and parameters
# Note that under Windows, the command, user/password/database and Sql script
# must all be specified as separate command strings, or SqlPlus does not see the correct arguments.
# Other systems may differ.
scr.command.1=sqlplus
scr.command.2=%1$s/%2$s@%3$s
scr.command.3=@%4$s

#Define named parameters for the arguments to SqlPlus, for the users convenience
scr.param-name.user=1
scr.param-name.password=2
scr.param-name.database=3
scr.param-name.scriptfile=4

No Comments »

February 11th, 2011
5:49 pm
Further h:outputStylesheet issues

Posted under JSF
Tags , , , , , , ,

I needed to load a custom style sheet for a composite component.

Primefaces has problems loading theme images correctly when using h:outputStylesheet as per here, but using a raw link tag was no good as I wanted to develop a custom component which loaded its own styles, i.e. it had no <head> section.

This post here indicates that if you don’t use the library attribute you can get h:outputStylesheet to work even with Primefaces themes.

In my case, I was not loading themes/images etc. so this was not an issue, but I still used the following directive and avoided use of the library attribute for simplicity:-

<h:outputStylesheet name=”uk.co.salientsoft/util/SSBreadcrumb.css”/>

This version worked. My initial attempts (which failed with a resource loading error) were as follows :-

<h:outputStylesheet name=”resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

<h:outputStylesheet name=”#{request.contextPath}/resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

In other words, with a css file stored in Eclipse under WebContent/resources/uk.co.salientsoft/util/SSBreadcrumb.css,  the above working example was correct, i.e. to load correctly, omit the context root and the resources level and use a relative reference without the preceding slash.

I did try to debug this by visiting the logger settings in Glassfish admin, then under the Log Levels tab, setting everything with JSF in it to finest! This did display an error when trying to load the resource:-

[#|2011-02-11T17:21:13.331+0000|FINE|glassfish3.0.1|javax.enterprise.resource.webcontainer.jsf.application|_ThreadID=31;_ThreadName=Thread-1;
ClassName=com.sun.faces.application.resource.ResourceHandlerImpl;MethodName=logMissingResource;
|JSF1064: Unable to find or serve resource, /SSBreadcrumb/resources/uk.co.salientsoft/util/SSBreadcrumb.css.|#]

However the error was not particularly informative as it just spat back to me the path I gave it to load. It would have been nice for it to tell me how it was mapping the path as then I could have seen the problem more easily.

Note however that using this page in Glassfish is a very convenient way to turn on logging in Glassfish, as it lists the common logger paths for you and gives a combo to select the level for each. You don’t have to go googling for the logger paths and edit a log properties file yourself. Note also that when you do this you must restart Glassfish for the log level changes to actually take effect.

No Comments »

February 2nd, 2011
7:56 pm
Primefaces Table Sorting–Common Gotchas

Posted under JSF
Tags , , , , , , , ,

Update 2/2/2011

According to this post here by Cagatay Civici, the Primefaces Project Leader, as at Primefaces 2.2M1, client side datatable is not supported and the dynamic attribute is deprecated from then on.
Seemingly it was becoming too hard to support all the table features on both client and server sides.
It is a shame that this was not documented better and more widely – the user manual still documents the dynamic attribute, and there are a number of posts about client side sorting (though in fairness they probably predate 2.2M1).

This behaviour exactly ties up with what I am seeing in my testing – the dynamic attribute does nothing, sortFunction is ignored, and all sorting is done via Ajax server side.

Original Post 2/2/2011

Having successfully got sorting working I was frustrated to find that a new simple example failed to work. Primefaces table sorting is pretty much transparent, requiring minimal effort and working out of the box. The lessons learned on this one are instructive so I summarise them below.

Details of Example and Problem

  1. The example fetched a list using JPA, stored the list in a view backing bean, then displayed it in a table with a sortable header.
  2. When the header was clicked, the up/down arrows were correctly displayed, but the data was not sorted – it was as if the request was ignored.
  3. It was not immediately obvious how the header click was handled – there was no obvious click event on the HTML element, and I could not see any Javascript running after a quick test with Firefox/Firebug. I gave up this line of attack but may look into it later as to how it all works. Some dynamic CSS pseudo classes/jQuery trickery may be involved.
  4. I was not certain as to whether the table was client side or server side/Ajax, even though it should have been client side by default. To diagnose the problem, I changed the value of the sortBy attribute in the column header to be an invalid bean property. The symptoms did not change, but an errors were logged in the Glassfish server log for each header click – “[#|2011-02-02T18:22:14.557+0000|SEVERE|glassfish3.0.1|org.primefaces.model.BeanPropertyComparator|_ThreadID=24;_ThreadName=Thread-1;|Error in sorting|#]”.
  5. This showed that the sort was being attempted but was failing due to the invalid property, which indicates that the sort was attempted server side. According to the Primefaces forum, for client side sorting, the sortBy property is not used as the displayed data is sorted.
  6. Interestingly, I would have expected Primefaces to use a client side table by default, but clearly it was not. Changing the dynamic property on the table tag to false explicitly had no effect and the behaviour was unchanged, so I will need to investigate client side tables further as for small data sets they are faster – I will update this post when I have done this.
  7. I turned on FINEST logging with Eclipselink in persistence.xml. Use <property name="eclipselink.logging.level" value="FINEST" /> to do this, and note that you need to bounce Glassfish to for a logging level change to be picked up. I noticed after this that the JPA query seemed to be rerunning very often, perhaps for every click of the sort header. This lead me to wonder if the backing bean was being recreated each time.

 

Cause and Solution

In the end, it was simply that I had not annotated the JSF backing bean as @SessionScoped (the example used CDI throughout, and did not use JSF managed beans). This meant the bean was request scoped by default, and was indeed being recreated – the sort was trying to do the correct thing, but the data was getting reloaded from the database in the original sort order each time!

Adding the correct annotation as above (and making a couple of the beans correctly implement serialisable to satisfy CDI/Weld) solved the problem.

This is a good example of where a problem cause is not immediately apparent from the symptoms.

Sample JSF page fragment showing the form containing the table

<h:form id="frmTest">   
    <util:themeSwitcher form="frmTest" outerStyle="clear: both; float: left; margin-bottom:20px;" innerStyleClass="ui-widget"/>
    <h:panelGroup layout="block" style="width:300px;">   
        <p:dataTable var="taxonomyNodes" value="#{taxonomyBrowser.taxonomyNodes}" scrollable="true"
             styleClass="clear #{fn:length(taxonomyBrowser.taxonomyNodes) lt 20 ? ‘ss-tableheader-scrolladjust-nobars’ : ‘ss-tableheader-scrolladjust-bars’}"
             height="460" > 
             <f:facet name="header">
                Client Side Sorting
             </f:facet>
             <p:column headerText="Category List"  sortBy="#{taxonomyNodes.text}">
                 <h:outputText value="#{taxonomyNodes.text}" />
             </p:column>           
        </p:dataTable>
    </h:panelGroup>
</h:form>

No Comments »

November 26th, 2010
8:25 pm
Using container managed JPA 2.0 with CDI/EJB 3.1/Glassfish 3

Posted under JPA
Tags , , , , , ,

Update

  • One issue to be aware of, which is not immediately obvious, is when populating a database from scripts. If the version column is left null (Eclipselink leaves it as nullable by default), then the null value causes an immediate OptimisticLockException to be thrown. This is because EclipseLink expects and checks for a zero as the initial value for a new record. If EclipseLink itself persists the record, then it writes a zero.
  • One good idea to resolve this would be to enforce version columns to be non null with a zero default – although it must be said that it would be helpful if EclipsLink did this automatically in response to the @Version annotation.
  • Population scripts should therefore set version to zero, unless it is set non null with a default of zero in JPA – this latter solution is cleaner and would be automatic for me because I create version columns in a mapped superclass used by all Entities. I have yet to test this out however.

 

Original Post

This follows on from a previous post relating to JPA 1.0/Glassfish 2.1, and contains a few notes and pointers relating to JPA 2.0 under Glassfish 3 with CDI/Weld.

Firstly, when using an EJB from a client, use CDI injection (@Inject) rather than the @EJB annotation, as CDI gives many additional benefits such as type safety.

In an EJB:-

  • You are using container managed transactions, and so simply have to inject an entity manager rather than create one from an entity manager factory.
  • The container managed entity manager can be injected with a simple @PersistenceContext annotation – the persistence unit name may be defaulted and is discovered automatically.
  • The container is responsible for entity manager lifetime/closing. Calling e.g. em.close at the end of a bean method is illegal and will make Glassfish angry. You do not want to make Glassfish angry – you end up with many long stack traces in the log which on the surface do not appear to relate to this trivial problem!

A major issue with container managed transactions is how to use optimistic locking and detect and handle optimistic lock exceptions correctly. This is detailed in Pro JPA 2, pages 355-357 (you can preview this in Google Books). The main problem is that in a server environment, the OptimisticLockException will simply be logged by the container which then throws an EJBException. Trying to catch an OptimisticLockException in the calling client is therefore doomed to failure – it will probably never be caught!

The solution is to call flush() on the entity manger (e.g. em.flush()) just before you are ready to complete the method. This forces a write to the database, locking resources at the end of the method so that the effects on concurrency are minimised. This allows us to handle an optimistic failure while we are still in control, without the container swallowing the exception. The ChangeCollisionException might contain the object which caused the exception, but it is not guarranteed to. If there were multiple objects in the transaction, we could have invoked getEntity() on the caught exception to see whether the offending object was included.

If we do get an exception from the flush() call, we can throw a domain specific application exception which the caller can recognise, i.e. convert an OptimisticLockException to our own ChangeCollisionException, avoiding coupling the caller to the internal semantics of JPA transactions. It is also desirable to factor out the code which calls flush() into our own method, e.g. flushChanges() to avoid the need for every method which needs to flush having to catch the optimistic lock exception and then throw our domain specific one – we can centralise the exception conversion in our own single method.

We must annotate the ChangeCollisionException class with @ApplicationException, which is an EJB container annotation, to indicate to the container that the exception is not really a system level one but should be thrown back to the client as-is. Normally defining an application exception will cause the container not to roll back the transaction, but this is an EJB 3 container notion. The persistence provider that threw the OptimisticLockException  (in this case Eclipselink) does not know about the special semantics of designated application exceptions and, seeing a runtime exception, will go ahead and mark the transaction for rollback. The client can now receive and handle the ChangeCollisionException and do something about it.

Here is an example of our exception class with the required annotation:-

@ApplicationException
public class ChangeCollisionException extends RunTimeException {
   public ChangeCollisionException() {super(); }
}

Here are code fragment examples from a stateless session bean showing the entity manager injection, and a client JSF model bean showing the CDI injection of the stateless session bean. Note that with EJB 3.1 it is not necessary to declare local or remote interfaces for an EJB as business interfaces are not a requirement. However, I always use an interface as it allows for example a mock version of a service layer to be easily swapped in for testing. CDI supports this conveniently via alternatives, whereby a mock version of a bean can be switched in via a setting in beans.xml for testing.

@Stateless
public class SentryServiceImpl implements SentryServiceLocal {

    @PersistenceContext
    private EntityManager em;

}

@Named
@Dependent
public class ModelBeanImpl implements ModelBean, Serializable {
    private static final long serialVersionUID = -366401344661990776L;
    private @Inject SentryServiceLocal sentryService;
… 
}

With container managed JPA and/or Glassfish your persistence.xml  can also be simplified, as you can define your data source in Glassfish rather than explicitly in persistence.xml, as described here.

Note that when defining a data source directly in persistence.xml,  some property names have been standardized for JPA 2.0, so have changed from e.g. eclipselink.jdbc.user to javax.persistence.jdbcuser. The following properties in persistence.xml are now standard:-

<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="javax.persistence.jdbc.user" value="sentry"/>
<property name="javax.persistence.jdbc.password" value="sentry"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>

An example persistence.xml used under JPA 2.0 follows:-

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="SentryPrototype" transaction-type="JTA">
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
      <jta-data-source>jdbc/SentryPool</jta-data-source>
      <properties>
       <property name="eclipselink.logging.level" value="INFO" />
       <property name="eclipselink.target-database" value="Oracle" />      
       <property name="eclipselink.ddl-generation.output-mode" value="database" />      
      </properties>
     </persistence-unit>
</persistence>

No Comments »

September 22nd, 2010
5:28 pm
Simple Primefaces JSF app displays blank page – incorrect glassfish deployment

Posted under Eclipse
Tags , , , , ,

I recreated a new simple JSF application from scratch, in the end making it identical to an existing one that worked.
Each time I ran it on Glassfish 3.0.1 from Eclipse, it displayed a blank page as if not being sent to the faces servlet.
I checked every detail in making the apps identical – checking every configuration file and the xhtml page.
I cleaned and republished to Glassfish, but still no joy.

In the end I did a detailed examination of the deployment folders under the Glassfish domain (Eclipse deploys its apps under domain1\eclipseApps\ assuming you are using the default domain of domain1). I discovered that the Primefaces jar, primefaces-2.2M1.jar had not been deployed, even though the library was added and the web deployment assembly page had an entry for it.

I tried explicitly removing the app from Glassfish by using the Add and Remove… option on Eclipse’s server context menu for the Glassfish server, and then adding it back. This time, the deployment folders were correct and the library was deployed correctly. The application then ran correctly and displayed the page.

The lesson from this is that deployment to Glassfish 3.0.1 from Helios can be flakey, and just using a clean in Eclipse is not always enough to really clean out any issues. Removing the app and re-adding may be needed. If there is any strange behaviour, the deployment folders under the Glassfish domain should be examined early on to check that everything did in fact deploy – sometimes Eclipse will say it is all ‘synchronised’ when it may not be, and you will not always get smoking gun errors to lead you to the problem!

No Comments »

September 19th, 2010
8:46 pm
Servlet Mapping Issues with Glassfish V3.0.1

Posted under Glassfish
Tags , , , ,

There seem to be some servlet mapping issues with Glassfish V3.0.1.

To summarize, the following outlines what the servlet mapping logic should do:-

  1. The <url-pattern> as below matches the input url and if there is a match, passes the url to the designated servlet (in this case the faces servlet).
  2. The url parts that match are stripped out, so that for extension mapping e.g. “*.jsf” pattern the “.jsf” is removed, and for path mapping e.g. “/faces/*” pattern the /faces subdirectory is removed.
  3. The javax.faces.DEFAULT_SUFFIX as below is applied to the result as a file type if one is not present, to give an actual file to be searched for. This is passed to the faces servlet for processing.

I tried the same combination in web.xml that I had used previously on Glassfish V2.1 with ICEfaces:-

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsf</param-value>
</context-param>

The actual file type was also .jsf (index.jsf in this case)
This gave rise to the following intermittent error when run – it would run once or twice and then blow up:-

url:  http://localhost/PrimeTest1/index.jsf
error:  javax.servlet.ServletException: PWC1232: Exceeded maximum depth for nested request dispatches: 20

Changing the actual file type and the above javax.faces.DEFAULT_SUFFIX value to .xhtml worked correctly in every case.
This error occurred both with a simple Primefaces test page:-

<html xmlns=’http://www.w3c.org/1999/xhtml’
xmlns:f=’http://java.sun.com/jsf/core’
xmlns:h=’http://java.sun.com/jsf/html’
xmlns:p=’http://primefaces.prime.com.tr/ui’>
<h:head> </h:head>
<h:body>
<p:editor />
</h:body>
</html>

and also with a simple JSF page in a non Primefaces JSF 2 faceted eclipse web project:-

<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<title>Test Page Title</title>
</head>
<body>
Test page body
</body>
</html>

It was therefore clear that the error was not Primefaces related, but appeared to be recursion caused by a servlet mapping issue. This post on the Glassfish Forums reported the issue – there was some discussion but no resolution, and I don’t think a bug has been raised.  This post also reported the same issue. Whilst I found a number of other posts too with what seemed like a related issue, there appeared to be no clear conclusion on any of them re the nature of the problem or a fix for it. I tried other combinations such as path mapping using “/faces/*” for the url pattern, “.jsf” for the default suffix, and “http://localhost/PrimeTest1/faces/index.jsf” for the url, but in this case the above error did not occur but a blank page was displayed. On examining the source for the page, it turned out to be the original page source i.e. it had not passed through the faces servlet.

My conclusion is that the servlet mapping/url pattern handling for Glassfish V3.0.1 has some issues, the precise nature of which is not clear. My solution is to use “.xhtml” for the actual filetypes and for the default suffix, and extension mapping using “*.jsf” for the url pattern – this combination works fine with no issues.

No Comments »

May 28th, 2010
2:34 pm
Java Dev setup 2 – Eclipse Helios/Eclipselink/Primefaces/Glassfish V3

Posted under Java
Tags , , , , ,

This follows on from this post which detailed my previous development stack based on ICEfaces and Glassfish V2.1.

This new stack uses Primefaces, which I now prefer to ICEfaces, for the following reasons (in no particular order):-

  1. It has a JSF2 full release – ICEfaces is still only in Beta for JSF2 (as is richFaces)
  2. According to various reviews, it is simpler and more lightweight – this may also be a factor contributing to it being further ahead in JSF2 support.
  3. It has fuller functionality as standard – with ICEfaces you need to subscribe to the commercial paid version to get some enhanced features such as the treetable.
  4. Like ICEfaces, it has a very clean and modern look and feel out of the box with minimal effort. It comes with many themes out of the box, and new themes may be constructed easily online via themeroller, with minimal CSS knowledge. The Primefaces CSS is structured to global theme skinning CSS from component specific CSS.
  5. The transparent AJAX bridge of ICEfaces was a compelling feature, as it gave completely transparent partial rendering, although at the expense of resources/performance due to the need for a replica DOM tree in the server which had to be kept in synch. However the new AJAX features of JSF2 perform this in a new way which is also now standard.
  6. It has a related component library, Touchfaces, which supports webkit based mobile browsers – widely compatible mobile support will be an important requirement for me.

The following operations should be performed :-

  1. Download and install the chosen Java SE JDK
  2. Download and install Glassfish V3.0.1 (in my case, the Web profile edition,as it is lighter, I don’t need the full EE feature set and can upgrade incrementally as required). Eclipse has a plugin for, and therefore a dependency on, Glassfish so we do the latter first.
  3. Download and install Eclipse (in my case, Eclipse Helios for Java EE, which includes Java EE 6, Eclipselink and all the web tools.
  4. Install the Glassfish Plugin for Eclipse (note the updated workaround for Helios), then create a new server for it in Eclipse – right click in the server view then select new and follow the wizard instructions. Note that by default, Eclipse Helios appears to configure the default JVM using the separate JRE (installed by default by the JDK kit) rather than the JDK, even though the JDK was installed. The Glassfish adapter complains about this JRE as it needs a JDK based one. You can just add an additional one for the JDK, and point the server create wizard at it, as detailed here
  5. Download and install Primefaces and its documentation. Primefaces is installed manually – I just download the jar to e.g. <workspace>\libraries\primefaces-2.2M1. I then create it as a User Library as detailed here. If you open a web page with the Eclipse web page editor, and display the palette, you will find all the Primefaces components under the http://primefaces.prime.com/tr/ui pallet entry (there may be other palette entries with the name primefaces which may be empty, and should be ignored). Code/tag completion for the components should all work correctly.
  6. Download Tomcat if required. I use this for some projects that need a servlet container but not Java EE. I have in the past used the windows service installer version, which is a self installing .exe and installs/runs Tomcat as a service. However note that this does not work under Windows 64-bit if you are using a 32 bit JVM. See here for a manual install process from the zip kit to give you all the functionality of the windows installer version, including run as a service, configuration utility, and system tray monitor/utility.

Comments and issues when test driving the resulting installation:-

  • The new Glassfish V3 is fully OSGI compliant, as is Eclipse, so the old issues about Eclipse losing sync as to whether Glassfish was started or not are a thing of the past. However, Eclipse would not use the configured Glassfish admin username/password, and always asked for username and password on startup. It also gave the impression that Eclipse was occasionally losing sync and did not detect properly that Glassfish had already been started externally. This can be avoided by setting Glassfish to have a null password. When I did this, Eclipse never asked for credentials and always seemed to sync with it properly. As this was a dev workstation with no inbound external access and a dev/test install of Glassfish, I was quite happy to run it without a password.
  • I imported the Primefaces Component Showcase .war file directly into Eclipse as a test to play around with. This ran fine, but initially any changes to the Java code did not deploy to Glassfish. It turned out that the code folders as loaded were not under the src folder where Eclipse was expecting them, so the auto build process was not compiling them. I just moved all the source up to where Eclipse was expecting them – it already had a set of empty packages there so I just dragged all the source files in the project explorer from where it originally was into the appropriate matching empty packages and all was well. Eclipse then compiled and deployed any Java changes I made correctly.
  • Glassfish 3 is supposed to start much faster than 2.1, it did not feel much faster but I did not do any testing on this. However, the new hot deployment on Glassfish 3 was good. I made some simple changes with the Primefaces component showcase, saved them and then did a republish. Some changes e.g. to xhtml files deployed almost instantly. Some java code changes that had larger scale impact took several seconds but were still hot deployed successfully. With Glassfish 2.1, I had found that the integration with Eclipse was a bit hit and miss – sometimes changes would hot deploy, but quite often things just got a bit sick/out of sync as already stated and Glassfish would need restarting, which was always the slow thing. This is why in the end I stuck with Tomcat for dev testing etc. as even though code changes triggered a restart, the start time was so much faster. I’m hoping for better things with Glassfish V3 and the reports I have seen are positive but will need to try it in anger for a while.

No Comments »