JSF facelets template packaging - jsf-2

As always, i'm a little confused.
Here https://community.jboss.org/wiki/ModularWebAppsWithJSF2 i've learned that it is easy and works out of the box to bundle templates in separate jars since JSF 2.0.
The only problem is: i can't get it working. I simply deploy a "page.xhtml" in all flavors (META-INF directory, resources directory, root; with and without faces-config.xml) in a jar that is included in the web application WEB-INF/lib and request something like http://host/demo/faces/page.xhtml or do an "include" or "decorate" on the template. I get an exception.
Here Java EE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR my favorite JSF teacher explains to use a custom ResourceResolver to do exactly this. As i debugged the resource resolving i have no doubt that this will work and will give it a try.
This is the question about the mechanics - what is the difference between the two approaches?
Which resources exactly are looked up in META-INF/resources automatically?

Facelets compositions (so, just plain *.xhtml pages, templates and include files) are resolved by ExternalContext#getResource() which delegates to ServletContext#getResource(). This requires a Servlet 3.x compatible container because /WEB-INF/lib/*.jar!/META-INF/resources resolving from is new since Servlet 3.0. If you aren't on Servlet 3.x yet, or want to put those JARs on a different location for some reason, then you'd need to create a custom ResourceResolver. See also How to create a modular JSF 2.0 application?
Facelets composite components and static resources (so, <cc:xxx> components and CSS/JS/image resources which are to be loaded by <h:outputStylesheet>, <h:outputScript> and <h:graphicImage>) are resolved from the classpath by ClassLoader#getResource(). To include the JAR file in the classpath scan of JSF, you'd need to include a JSF 2.x compatible faces-config.xml file in the /META-INF folder of the JAR file. The same story applies to #ManagedBean, #FacesValidator, #FacesConverter, #FacesComponent and other JSF artifacts.
When developing in Eclipse, you can choose Web > Web Fragment Project to create such a module project. It is not much different from a normal Java project, expect that it will implicitly include JavaScript facet and a targeted runtime, autocreate a /META-INF/web-fragment.xml file and get associated with an existing Dynamic Web Project by adding itself as a deployment assembly to that project.
You can also use an existing standard Java project with the right folder structure prepared. The /META-INF folder has to go in Java source folder. The web-fragment.xml file is by the way optional. You just have to manually add the Java project to the Deployment Assembly section of the main web project properties. Do not add it as another project in project's Build Path section.
When you're (manually) building a JAR file out of it, you need to make sure that the directory entries are added to the JAR, otherwise Facelets compositions can't be resolved. If you're building by build tools like Eclipse/Ant/Maven/etc, this has also to be taken into account. If this is not controllable, a custom ResourceResolver is the most reliable approach.

Related

Controllers folder missing Umbraco 8

I installed Umbraco 8.4 as per the instructions found at https://our.umbraco.com/documentation/Getting-Started/Setup/Install/install-umbraco-with-nuget
Once done within Visual Studio 2017 i tried to created a new Controller and the folder (Controllers) was missing.
I'm not sure if i've missed something but i didnt want to create the folder manually in case it introduces new problems later down the line.
I thought to recreate the project but instead of selecting Empty as the project to use MVC but after reading through a few threads it seems the correct way is to select an empty project.
Under the bin directory i do see System.Web.Mvc.dll
Am i missing something?
You should definitely not use the MVC project template when creating a new project - that will add all sorts of dependencies that will likely conflict with what comes with the Umbraco NuGet package.
Go with the "Empty" template and then add in the NuGet and it will give you the dependencies you need for Umbraco to run. If you need to add in other stuff from MVC afterwards, you can add these in a version that aligns with what the Umbraco package has added.
In regards to the Controllers folder - it really doesn't matter where this folder lives or what it is called. Controllers are registered by other means. You are totally fine to create this folder manually and call it whatever you prefer.
I think most people actually prefer to keep Controllers in a completely separate project in the VS solution. Then reference that project by your main project to ensure the compiled DLL is included in your web project - and thereby your controllers can be used by the Umbraco website itself. By doing this, you get a clean separation of your .cs source files so you won't accidentally be deploying those when you deploy your site. To do this you would of course require to add UmbracoCms.Core NuGet package to your other project in order to use Umbraco functionality.
Keep in mind if you are adding plain MVC controllers (not inheriting from the Umbraco base controllers - and therefore not getting automatically registered) you will need to manually register these controllers in the route table in order to access them.
This is no different from what you would do in a normal ASP.NET MVC project, but since this isn't added by default in an Umbraco project - you need to do it yourself.
See this answer for instructions on how to do it: https://stackoverflow.com/a/56972929/336105

Override bootstrap in .net core 2.0 using less

In good old ASP.NET we would install Bootstrap as a NuGet package and it would install all the files in the ~/Content/bootstrap directory. This made it easy to create a custom bootstrap.less file that imported Bootstrap so that we could override what we wanted while still keeping the library intact so it could be updated at any time.
For example I could do this in my custom less file to enable a special bootswatch theme with some custom variables and overrides. I could then compile it and add it to the site css.
#import "bootstrap/bootstrap.less";
#import "bootstrap/_variables.less";
#import "bootstrap/_bootswatch.less";
#import "custom.less";
In dot net core 2.0 there is no ~/Content directory by default and css is really served from the new wwwrootdirectory. When installing Bootstrap through NuGet now, it is added as a "Dependency". I can't find a way to import the bootstrap less files as I used to though since I don't know the path, if there even is one.
I have created a custom ~/Styles/bootstrap.less file in which I try to use the imports above but the compiler can't find them. I have found the .less files in /packages/bootstrap.less.3.3.7/content/Content/bootstrap.less in my solution root but that does not seem to be accessible to the import-statements.
#import '../../packages/bootstrap.less.3.3.7/content/Content/bootstrap.less';
The error I get is simply:
FileError: '../../packages/bootstrap.less.3.3.7/content/Content/bootstrap.less' wasn't found.
Tried - [SOLUTIONPATH]\packages\bootstrap.less.3.3.7\content\Content\bootstrap.less,
....\packages\bootstrap.less.3.3.7\content\Content\bootstrap.less in \Styles_bootstrap.less
How can I override the bootstrap less files? Do I have to download bootstrap myself into my ~/Styles/ directory to be able to import them? That would ruin the possibility of updating through NuGet :/
.net core has stopped supporting Nugets for client side codes. Creating a new .net core project with either vs 2017 or using the cli dotnet new mvc would by default include the bower packages on the wwwroot/lib folder. To manage bower packages you can right click on the project and select "manage bower packages". Also note that .net core mvc by default is only configured to use the wwwroot folder as the client side content. Besides this, the compiled views are the only other content that are given to the client. This means that and Styles or Contents folder you create wouldn't be a client side code by default. You can add theses folders in the set up but its not recommended. The js and css files can be found in folders inside wwwroot.

What features does the Struts2 development plugin for your IDE offer?

This concerns the state of Struts2 framework tooling, although currently I use no IDE plug-in, preferring to create projects with maven from scratch. At one time I did use the Netbeans Struts2 plugin but stopped when support lapsed for a time between IDE releases.
It is important to know the state of current tooling and so ask:
What features are offered by the Struts2 IDE framework plugin for your IDE(s)?
Are there any design issues with the plugin? (flaws such as wanting to include old or outdated libraries)
This answer applies to the the Netbeans plugin found here: http://plugins.netbeans.org/plugin/39218 (at time of writing the last updated was : 2011-12-17)
Features
When Starting a new project. File > New Project > Web Application
You now have the option of adding struts2 support, which can product a struts2 demo project.
Not tested, but should assist in validation.xml files.
Issues and Limitations
There is no support to create sources in a Maven Web application.
If you use annotations for validation the plug-in does not help.
There is no more support in struts.xml than provided by the IDE naturally. I would have really liked to see property suggestions at the very least, and it would have been very nice to see a list of name values when in a struts.xml constant tag. The IDE does do auto completion in applicationContext.xml where it expects a class, this would be really helpful in struts.xml for the class attribute of the action tag (among other places).
There is an annoying issue of the plug-in creating struts.xml files with a special icon but when creating new xml documents this icon does not apply (should be applied on the basis of the dtd) so you need to copy and paste the file to get the icon and then change the contents.
It only provides struts2 version 2.0.14 or 2.2.3
Over all I do not recommend this plug-in over a standard Maven Project and manually adding the dependencies.

ASP.NET MVC: files containing extension methods inside App_Code must have Build Action "None"?

This seems to be the only thing that works:
If a .cs file is inside App_Code...
And does not contain extension methods: set the build action to "Compile"; otherwise no other source code in the project knows of its existence.
And contains extension methods: set the build action to "None"; otherwise you get an error that the reference to x.Foo is ambiguous between MyExtensions.Foo and MyExtensions.Foo.
If a .cs file is outside App_Code, inside a folder called Helpers, it must have build action set to "Compile," regardless of whether or not it contains extension methods.
I don't understand this behavior. I wasn't sure that ASP.NET MVC contained any special privileges for App_Code, but it looks like it does... but only in the sense that it auto-compiles extension-method containing .cs files, even when the build action is set to "None"?? Someone please explain.
I'm assuming you've created a Web Application Project, not a Web Site Project. The App_Code folder in an ASP.NET application is special. It is designed to allow you to drop in code to have it compiled with the website in place. Because of this, the project items are marked as "None" to make sure they are not compiled by Visual Studio. When you publish a Web Site Project to your hosted environment, the code files themselves are copied in the App_Code folder, and this is compiled into a seperate assembly by the ASP.NET runtime.
Now, when you create an MVC Web Application, you must remember that it is not the same project type as a Web Site Project. An MVC Web Application will compile locally to an assembly in your /bin directory. If you add an App_Code folder to your project with your code in and you change the Build type to Compile, you run into problems because:
Your MVC application has compiled and includes a MyExtensions.Foo type and,
ASP.NET is compiling the App_Code folder which also has a MyExtensions.Foo type.
My recommendation is to avoid using App_Code. I tend not to, as I favour a more concise project structure. Use the Models folder for code, or create other folders.....
If you really want to use an App_Code folder, it might be better to mark the build action of any of the files as "Content" to ensure they are copied to the output directory when publishing your site.

Struts2 in RAD raises error - xwork has already been loaded by bean

I am using RAD 7.0 for developing Struts2 app. When I run the web app inside RAD on websphere 6.1, I get following error:
could not be initialized]: Unable to load bean: type:
class:com.opensymphony.xwork2.ObjectFactory - bean -
wsjar:file:/C:/workspace_test/Jars/struts2-core-2.0.11.2.jar!/struts-default.xml:30:72
at
com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:208)
.... more Caused by: Bean type class
com.opensymphony.xwork2.ObjectFactory with the name xwork has already
been loaded by bean -
wsjar:file:/C:/workspace_test/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/Struts2Demo/WEB-INF/lib/struts2-core-2.0.11.2.jar!/struts-default.xml:30:72
- bean - wsjar:file:/C:/workspace_test/Jars/struts2-core-2.0.11.2.jar!/struts-default.xml:30:72
at
com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:193)
... 33 more
I understand that this is due to 2 copies of struts2 jars. Let me explain how I have configured my web project in the RAD environment.
I have a Web project called "Struts2Demo" project. And a separate project called "JARS" which contains all the required jars.
All the required jars for Struts2Demo web project are configured using "J2EE Module Dependencies - Web Libraries" referencing "JARS" project.
So the RAD while loading the web app is loading the jars from "JARS" project and also from the eclipse temp folder "/C:/workspace_test/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/Struts2Demo/WEB-INF/lib/", hence the error.
So, my question is there any way to fix this configuration other than putting required jars in WEB-INF/lib
Zero experience with RAD. But the standard practice, is to put the struts jars (and, in general, most of the jars) in the WEB-INF/lib of each web-application. The duplication inconvenience is usually outweighed by the isolation of classes from each library (different classloaders) among webapps, which helps to avoid problems as yours.

Resources