Showing posts with label Apache. Show all posts
Showing posts with label Apache. Show all posts

Thursday, November 20, 2014

Setting JAVA_HOME for Bitnami Apache Tomcat stack as a Windows Service

tl;dr 

You can't set it to a different JAVA_HOME, you'll have to set your JAVA_HOME to the Bitnami JDK if you want a consistent JDK.

Setting the Bitnami Tomcat JAVA_HOME on Windows

The Problem

The Bitnami Tomcat stack packages it's own JDK and uses it over the existing JAVA_HOME directory.  This means that if you want a consistent JDK between your unit tests and in-container tests (and you do) you either need to set your usual JAVA_HOME to the Tomcat version or get Tomcat to use the system JAVA_HOME.

The Background

This tutorial is about the latter, as I have already installed the Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files into the system JAVA_HOME (as per a blog post on Suhorish!) and didn't want to do it again.

The Research

After going through several stackoverflow questions and a Bitnami community post I found that they all suggested changing the various Windows BAT files in /bin and /scripts.  This did not work.

The Experiments

Digging into the Windows Service properties I found that the tomcat7.exe is called directly, therefore bypassing all of these scripts.

I eventually decided to use Junction Link Magic to create a hard link from Bitnami/tomcatstack/java to my actual JAVA_HOME... and that didn't work.  The Tomcat service will fail with Application Error 1 and an event error of:
The tomcatstackTomcat service terminated with the following service-specific error: 
Incorrect function.

So I tried to bypass the service by calling the scripts directly, also to no avail.

The Conclusion

This led me to the tl;dr at the start of this article.  I hate admitting defeat.

Tuesday, October 1, 2013

Here Be Dragons: Apache DeltaSpike on Google App Engine

I recently tried using Apache DeltaSpike, CDI extensions that are the official successor to Seam. On the Google App Engine.

Unfortunately, as of this writing (and version .4 of DeltaSpike) the library triggers the infamous Restricted Class error:

[INFO] Oct 01, 2013 11:59:04 PM com.sun.faces.config.ConfigureListener contextInitialized
[INFO] SEVERE: Critical error during deployment: 
[INFO] com.sun.faces.config.ConfigurationException: Factory 'javax.faces.context.FacesContextFactory' was not configured properly.
[INFO]  at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:330)
[INFO]  at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:236)
[INFO]  at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:435)
[INFO]  at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:214)
[INFO]  at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[INFO]  at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[INFO]  at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[INFO]  at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[INFO]  at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[INFO]  at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO]  at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO]  at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO]  at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO]  at org.mortbay.jetty.Server.doStart(Server.java:224)
[INFO]  at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO]  at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:249)
[INFO]  at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:306)
[INFO]  at com.google.appengine.tools.development.AutomaticInstanceHolder.startUp(AutomaticInstanceHolder.java:26)
[INFO]  at com.google.appengine.tools.development.AbstractModule.startup(AbstractModule.java:79)
[INFO]  at com.google.appengine.tools.development.Modules.startup(Modules.java:88)
[INFO]  at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:240)
[INFO]  at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:399)
[INFO]  at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
[INFO]  at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:334)
[INFO]  at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:310)
[INFO] Caused by: javax.faces.FacesException: org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory
[INFO]  at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:710)
[INFO]  at javax.faces.FactoryFinder.getImplementationInstance(FactoryFinder.java:572)
[INFO]  at javax.faces.FactoryFinder.access$500(FactoryFinder.java:140)
[INFO]  at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:1120)
[INFO]  at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:379)
[INFO]  at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:328)
[INFO]  ... 24 more
[INFO] Caused by: java.lang.reflect.InvocationTargetException
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
[INFO]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[INFO]  at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:127)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:135)
[INFO]  at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:690)
[INFO]  ... 29 more
[INFO] Caused by: java.util.ServiceConfigurationError: org.apache.deltaspike.core.spi.config.ConfigSourceProvider: Provider org.apache.deltaspike.core.impl.config.DefaultConfigSourceProvider could not be instantiated: java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google  App Engine developer's guide for more details.
[INFO]  at java.util.ServiceLoader.fail(ServiceLoader.java:224)
[INFO]  at java.util.ServiceLoader.access$100(ServiceLoader.java:181)
[INFO]  at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:370)
[INFO]  at java.util.ServiceLoader$1.next(ServiceLoader.java:438)
[INFO]  at org.apache.deltaspike.core.util.ServiceUtils.loadServiceImplementations(ServiceUtils.java:55)
[INFO]  at org.apache.deltaspike.core.api.config.ConfigResolver.resolveConfigSources(ConfigResolver.java:224)
[INFO]  at org.apache.deltaspike.core.api.config.ConfigResolver.getConfigSources(ConfigResolver.java:203)
[INFO]  at org.apache.deltaspike.core.api.config.ConfigResolver.getAllPropertyValues(ConfigResolver.java:160)
[INFO]  at org.apache.deltaspike.core.util.ClassDeactivationUtils.initConfiguredClassDeactivators(ClassDeactivationUtils.java:152)
[INFO]  at org.apache.deltaspike.core.util.ClassDeactivationUtils.getClassDeactivators(ClassDeactivationUtils.java:143)
[INFO]  at org.apache.deltaspike.core.util.ClassDeactivationUtils.initDeactivatableCacheFor(ClassDeactivationUtils.java:88)
[INFO]  at org.apache.deltaspike.core.util.ClassDeactivationUtils.isActivated(ClassDeactivationUtils.java:73)
[INFO]  at org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory.<init>(DeltaSpikeFacesContextFactory.java:42)
[INFO]  ... 36 more
[INFO] Caused by: java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google  App Engine developer's guide for more details.
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
[INFO]  at org.apache.deltaspike.core.impl.util.JndiUtils.<clinit>(JndiUtils.java:51)
[INFO]  at java.lang.Class.forName0(Native Method)
[INFO]  at java.lang.Class.forName(Class.java:186)
[INFO]  at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)
[INFO]  at org.apache.deltaspike.core.impl.config.LocalJndiConfigSource.getPropertyValue(LocalJndiConfigSource.java:53)
[INFO]  at org.apache.deltaspike.core.impl.config.BaseConfigSource.initOrdinal(BaseConfigSource.java:54)
[INFO]  at org.apache.deltaspike.core.impl.config.LocalJndiConfigSource.<init>(LocalJndiConfigSource.java:39)
[INFO]  at org.apache.deltaspike.core.impl.config.DefaultConfigSourceProvider.<init>(DefaultConfigSourceProvider.java:49)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
[INFO]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[INFO]  at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
[INFO]  at java.lang.Class.newInstance0(Class.java:372)
[INFO]  at java.lang.Class.newInstance(Class.java:325)
[INFO]  at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:362)
[INFO]  ... 46 more

Monday, September 16, 2013

Logging out with Apache Shiro and Spring Web Flow

In this article I will attempt to save others the frustration of figuring out how to log out with Apache Shiro security in a Spring Web Flow app. The Shiro site has a nice link on Spring integration and from incorporating that and finding the Subject.logout() method, only to use it resulting in a Spring Web Flow error about being unable to serialize a non-existent session (since you just killed it):
[INFO] Caused by: org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key 'e1s2' -- perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.
[INFO]  at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:172)
[INFO]  at org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository.updateFlowExecutionSnapshot(DefaultFlowExecutionRepository.java:141)
[INFO]  at org.springframework.webflow.engine.impl.FlowExecutionImpl.updateCurrentFlowExecutionSnapshot(FlowExecutionImpl.java:427)
[INFO]  at org.springframework.webflow.engine.impl.RequestControlContextImpl.updateCurrentFlowExecutionSnapshot(RequestControlContextImpl.java:222)
[INFO]  at org.springframework.webflow.engine.ViewState.updateHistory(ViewState.java:324)
[INFO]  at org.springframework.webflow.engine.ViewState.exit(ViewState.java:248)
[INFO]  at org.springframework.webflow.engine.Transition.execute(Transition.java:225)
[INFO]  at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
[INFO]  at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
[INFO]  at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
[INFO]  at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
[INFO]  at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
[INFO]  at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
[INFO]  at org.springframework.webflow.engine.ViewState.handleEvent(ViewState.java:231)
[INFO]  at org.springframework.webflow.engine.ViewState.resume(ViewState.java:195)
[INFO]  at org.springframework.webflow.engine.Flow.resume(Flow.java:537)
[INFO]  at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
[INFO]  ... 54 more
[INFO] Caused by: org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '1' -- perhaps this conversation has ended? 
[INFO]  at org.springframework.webflow.conversation.impl.ConversationContainer.getConversation(ConversationContainer.java:126)
[INFO]  at org.springframework.webflow.conversation.impl.SessionBindingConversationManager.getConversation(SessionBindingConversationManager.java:117)
[INFO]  at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:183)
[INFO]  at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:170)
[INFO]  ... 70 more
[INFO] 
From digging deeper into the documentation you can find a log out filter for Shiro, but using this instead of Subject.logout() in an action method (i.e. the action attribute of a button or link, not an action-state) will still give the same error. Lastly, you can find a blog post by BalusC (under Programmatic Logout) that describes how to tell JSF that you just logged out via Omnifaces in the action but that doesn't quite do the trick either. However, calling Subject.logout(), the code BalusC describes and then returning NULL from the action does it. Apparently the log out code doesn't stop SWF from trying to resume the flow, but returning null does. To summarize, the following will let you log out of Apache Shiro and Spring Web Flow when bound to the action of something like an h:button:
 public String logoutAction() throws IOException {
  SecurityUtils.getSubject().logout();
  Faces.invalidateSession();
  Faces.redirect("/faces/loginflow");
  return null;
 }

Wednesday, August 14, 2013

JSF 2.2 with Google App Engine: A Hurricane of Errors

Three days trying to do what should be a simple upgrade from the JSP Hello World to JSF and it still isn't working.

Long story short, when you get started with Google App Engine you'll find a nifty tutorial from Google that gets you up and going with a simple Guestbook JSP project.  I use Maven with my Eclipse so I used the Maven Archetype instead (also JSP).  At the time I was unable to find a detailed tutorial that starts with JSF to begin with.  There will be a future post with my experience of using that one instead (UPDATE: done, see this post).

As is, I setup the configuration for JSF and Apache MyFaces doing it the old-fashioned, manual way.  I had problems finding documentation on how to do it (and couldn't even find it again).  So, this is what NOT to do:

  1. Include Apache MyFaces in your Maven dependencies.
  2. Update your web.xml to be at least version 2.5 (this is actually a good idea) and include the following
(UPDATE: below code is properly presented now)

  Faces Servlet
  javax.faces.webapp.FacesServlet
  1



  Faces Servlet
  /faces/*
  3. Put a simple JSF hello world file into your /faces directory and load it up.  Even better, don't use an EL #{} expression so that you don't know that EL is broken until much, much later.

As stated, this worked three years ago with Eclipse 3.6 or so, but NOW Eclipse 4.3 Kepler has a concept called Project Facets under the Project properties screen and if you don't specify that you're using JSF here... it blows away your custom web.xml to the default jsp version.  This was Gotcha #1.

After reverting that mess and configuring the Facet I'm expecting a smooth ride... but get the now dredded: javax.naming.InitialContext is a restricted class error, and try the fix suggested by the link just previous.  I do not catch the subtext that this fix is only for Sun's (not Apache's) JSF implementation, and for an older version than I'm using at that!  So I change to Sun's JSF, track down the new WebConfiguration.java and comment out the needed code and at least it compiles but it still doesn't work, so I go back to MyFaces, download the source and comment out their references that I track down.  Then I have to track down a couple of other libraries that the one source file uses and it finally compiles.  At least the Hello World works at this point.  Now I know that the more recent JSF implementations have this issue fixed!  So don't mess around with commenting out the InitialContext code, just change the JSF implementation (the latest Mojarra works).  If you're keeping track, these are Gotchas 2 to 7.

Upgrading to Facelets is as easy as it is supposed to be.  However, this is when I realize that my EL isn't working.  After trying and reading various articles I came across new errors.  I found that I got ClassNotFoundException: javax.faces.webapp.FacesServlet and the ELResolvers for JSF were not registered with the JSP container not because it could not be found, but because it could be found too often (and I had to include it as provided instead of as a jar).  The novel cannot_find_facelet_taglib turned out to just be an Eclipse thing.  All in all, I still wasn't able to patch it up after finding about 6-12 other gotchas.

Wednesday, January 16, 2013

Wordpress & XAMPP

So, if you're not familiar XAMPP is an all-in-one solution running on multiple platforms (X), Apache, MySql, Perl and PHP (and Tomcat).  I've used this well for PHP development before back around 2006.

However when I went to use this to host a local Wordpress instance for development purposes I kept getting an invalid database connection message.  After hours of struggle and frustration, wikihow had a great article with a step by step tutorial on this.  It turned out my DB encoding was wrong (thanks regular tutorial and error messages for being so obtuse!).

Wednesday, November 16, 2011

Not as Easy as it Looks

After trying to migrate from JSF 1.2 to 2.0 with these StackOverflow questions I found that if you're upgrading to Facelets 2.0 you also need to upgrade to Apache Trinidad 2.0.

Maven info can be found at this post at Thoean.  It's supposed to have more content, but I couldn't figure out how to get to it.

It appears that that is the best upgrade guide that I could find, and this Andy Schwartz blog post is great for what features you get when it's all over.

Part 2 is about moving from OGNL to SpEL.