Using maven archetype to create an AEM project - aem

When we generate a maven AEM project, how do we decide the archetype to use? What are the deciding factors and best practices for the same?

You can find the a baseline structure provided in Adobe-Marketing-Cloud space on Github - aem-project-archetype
This is a very basic structure to start with and provides you following modules -
Core : Core bundle (java code goes here)
it.launcher - Baseline bundle to support Integration Tests with AEM
it.test - Integrations tests
ui.apps - Module for your components,template etc code.
ui.content - Project sample/test content or may be actual content (actual content in codebase is not a good practice)
Important thing to know prior to deciding the structure for your project is -
Is the implementation for multiple brands or to be used across multiple projects
Is there a need of platform which provides the basic/core functionality/features to be extended by different implementations
What is the roadmap for the project
That said, a best practice is to separate interface and implementation into different modules. Most modules will have 3 sub-modules (api, core and package).
api: OSGi specification describes a modular system with separate api
bundle
core: An implementation bundle providing a service
package: Packaging 2 bundles to generate AEM content package.
There can also be packages which consists of contents without api/service. Such modules do not follow convention of osgi bundles, for example configuration, components, design etc.
In most of the our AEM implementations, the project was generated from the com.cqblueprints.archetypes:multi-module Maven Archetype and its folder structure was refactored according to AEM 6 Implementation Guidelines.
All modules created are to organize dependencies in better way and have clean separation of package deployment.
Number of modules can vary depending on the project, some common reusable modules as baseline may include -
1. build-settings
This folder can hold commonly used settings and scripts :
- CI server scripts/setting
- Maven's settings.xml
- Reusable bash profile specific to project etc.
2. Common Module
This will have [api,core and content sub-modules]. As name suggests this should have generic service or utility classes that do not belong to any module or can be used across all modules. Be extra careful and justify reason for adding classes in this module else as a malpractice everything ends up on common module.
3. UI Module
This will have [api (optional if you need OSGI services here),core and content sub-modules].
- The core module holds all your SlingModel, WCMUse extensions and
supporting Pojos.
- Content package to contain all your UI functionality related to components, templates. Its important to structure this module correctly so that addition of components, pages etc doesn't make it unmanageable.
We created following structure in the content module, /apps/<your_project>/ui
components : all components goes here. Further sub categorized as [content,global,scripts]
install
page : page components
templates : page templates
4. Configurations Module
This module to carry OSGI, Cloud Configurations and if implemented the /conf based implementations as well. Conf based implementation sample here
OSGI Configurations Module : Package module with all configurations as content.
Cloud Configuration Module : Package module with all configurations as content
5. Sling Error Handler Module
Any error handling content should reside here. Sample configuration has author mode display error stack and in publish mode it returns 404 response.
6. Designs Module
Any error handling content should reside here. Sample configruation has author mode display error stack and in publish mode it returns 404 response.
7. Content Module
Packages sample content and/or test content. In some implementations we chose to keep test content as separate module.
8. Complete Module
The is the package module that gets compiled at the last and combines all the packages generated in above modules into a single package for deployment to the server.
If your application has lot of business logic or processing you could add up more modules, for instance in couple of projects we have following additional modules as well -
Grunt/Gulp build
Services/Operations (for business layer)
Validations
Data Import
Incontainer tests
Incontainer test content
In addition to these we created a pom project that abstracts all the dependencies, configurations, plugins, profiles specific to AEM project and used that as a parent for the project POM. This cleaned up the project pom and allowed for reusability across projects for same client.
Sample parent.pom here

Related

What is the right way to create JUnit tests for Eclipse fragments?

One of the most common uses of eclipse fragments is as a container for JUnit test classes. But how to write JUnit tests for Eclipse fragment when it plays another, more important role? For example, when it has platform specific code.
The problem is that it is impossible to create a fragment for a fragment. And you can't write tests for host plug-in to test the fragment because it doesn't even compile as a fragment is "merged" into a host only at runtime.
I don't know of a satisfactory solution, however, you may want to consider these workarounds.
Eclipse-ExtensibleAPI
You can use the Eclipse-ExtensibleAPI manifest header like this
Eclipse-ExtensibleAPI: true
It causes the packages exported by the fragment to be re-exported by the host bundle. Now you can create a test bundle that imports the desired packages and therefore has access to the public types in the fragment.
This isn't as close as test-fragments where you benefit from tests and production code using the same class loader that gives access to package-private types and methods. But you can at least test through the publicly accessible means.
Note, however, that this header is specific to Eclipse PDE and not part of the OSGi specification. Hence you are tied to this development environment. Furthermore, the packages of the fragment will be exported through its host bundle and will be visible not only for the test bundle but for all bundles.
Java Library
If your fragment has few dependencies and doesn't require the OSGi/Eclipse runtime you could consider treating it as a plain Java library w.r.t tests. Another sibling Java project could contain tests and have a project-dependency (Properties > Java Build Path > Projects) on the fragment project. Again, access to package-private members would not work.
And if you use a build tool like Maven/Tycho, some extra work would be required to declare dependencies and execute these tests during the build.
Bndtools
You could also look into Bndtools to see if this development tool fits your needs better than the Eclipse Plug-in Development Environment (PDE).
Plain JUnit tests are held in a separate source folder in the same project as the production code. This would give your test code access to the production code in the same way as if test-fragments were used.
Bndtools also supports executing integration tests, though I doubt that you would have access to the fragment code other than through services or other API provided by the fragment.
For CI-builds, Bndtools projects usually use Maven or Gradle with the help of the respective bnd(http://bnd.bndtools.org/) plug-in. Just as Maven/Tycho is used to build and package PDE projects.
Since Bndtools is an IDE extension to develop OSGi bundles, it doesn't know about Eclipse plug-in specificities such as extensions declared in the plugin.xml. Hence there is no builder and editor for these artifacts. But if you are lucky, you may even be able to use the PDE builder to show error markers for invalid extensions and extension points.
Another downside that comes with having production- and test-code in the same project, is that pure test dependencies like JUnit, mock libraries, etc. are also visible for the production code at development time.
Of course, the produced (fragment) bundles do neither contain test code nor test dependencies.
However, Bndtools itself is developed with Bndtools. So there is proof that Bndtools can be used to write Eclipse plug-ins.

Working modular example for JavaFx8 + OSGi + Gradle multiproject without additional tooling?

I am stuck with a problem I can't solve for weaks now.
I have to create a modular JavaFX application, where each component defines a "domain unit" (with models+views+controllers). Each component can be loaded into a "shell application" (as a content of a tab view or multiple tab views) and the modules can depend on another module(s) (their content in tabs won't appear if their dependency is not loaded).
That's why I was planning to create an OSGi based JavaFX application and build it with Gradle as a multiproject.
I've already tried dozens of tutorials with no success and I experienced, that most of these tutorials:
are outdated, not reproducible (e.g. elcipse's interface, templates have changed, bndtools tutorials doesn't seem to work, equinox doesn't seem to to work without felix, javafx8+osgi generate different kind of problems... etc.)
are too complex for a beginner (I just started to learn OSGi and Gradle) and they skip important steps I am not aware of
contain too much "IDE magic" (I would rather type some code instead of filling forms in eclipse)
some solve the problem with different tools (maven/tycho, bndtools, e(fx)clipse), but I've got no time to learn them
I want my application to be independent from IDE's environment. I don't want to use e(fx)clipse or BndTools if possible (even if they can make the build process easier)..
I'm experimenting with OSGi implementations, that's why I would rather not to choose between Equinox, Felix or Karaf.
I've already programmed similar application in .NET world, but it seems to me impossible to do the same in Java world..
My main questions are:
is it possible to do what I have imagined?
how to create a gradle multiproject what is IDE/platform independent (if projects are not tied to eclipse environment, or equinox, but it's possible to use them)?
what are the best ways to initialize the application (shell application + modules) and load the independent modules/bundles/components?
how to separate my views into subprojects (what build.gradle files should contain)?
how to solve the javafx8 inpompatibility with osgi?
what is the correct way to apply javafx plugin in gradle?
what tutorials are the most relevant?
is there any working example, pattern or tutorial (without using additional tools) what solve the same problem (using only osgi+javafx+gradle)?
I could group your questions in differents topic:
OSGI
You just need to google around to find out that is a java specification that encourages modularization, provides hot-deploy feature, and so on. As I told you, is just an specification like Java Servlet API, so they are different providers or implementers of OSGI Specification such as Felix and Equinox. Karaf instead is a OSGI container based on Felix, so you get all felix benefits and in addiction karaf natives features. For that reason I encourage you to take Karaf into use.
Aquote BndTool
In order to satisfy the OSGI specification, you need that your modules contains a MANIFEST.MF which holds all dependency information so Karaf create the classloader required for your bundles.
Assuming that you don't want to create that MANIFEST.MF files by hand, you could take aqute/bndtool for that. Don't get mess with bndtool for eclipse plugin. That application can be used from command line, from a maven plugin, or from a gradle plugin. Basically scans your classes, check the imports, and create a MANIFEST.MF automatically.
Gradle
If you choose gradle as a build tool, then you can take into use: Bnd Gradle plugin. It's easy to set up, but follow the instruction for non-workspace plugin. If you don't want to use BndTool for eclipse. IDE independent solution, you mentioned in your question.
MultiProject Layout
How the project layout should look like, depends on your modularization, but you can have a look on this layout example that uses gradle+osgi+karaf for a multiproject. Perhaps inspires you.
https://github.com/antoniomaria/gradle-karaf-bnd-project

GWT: Is it possible to refer non-GWT modules that contain GWT-independent presenters?

For curiosity's sake, I'm developing a small experimental platform/environment-agnostic MVP framework-like thing that's supposed to be as much platform independent as possible. Currently it consists of dumb models, platform-independent presenters (defined in a single abstract main application module), and platform-dependent views (currently there are experiments with Swing, Android and terminal-friendly environment). However, I'm in trouble trying to make GWT another available platform because it requires modules inheritance via .gwt.xml files. Is there a good way of inheriting non-GWT modules somehow, and keep that abstract platform-independent module .gwt.xml-free, but still available for the GWT? If it's worthy: all modules are built with Maven, and the project structure is as follows:
[root]
[app] --- platform-independent application
pom.xml -- references fx
[app-gwt] --- GWT-views, entry point, etc
pom.xml --- references app, fx, fx-gwt
.... App.gwt.xml --- references Fx.gwt.xml
[fx] --- the core itself
pom.xml --- references nothing
[fx-gwt] --- GWT-specific adapters for the fx module
pom.xml --- references fx
.... Fx.gwt.xml --- references GWT core
pom.xml
Simply speaking, I don't want either app or fx to be GWT-related in any case. Also, I thought that modifying <source path="..."> (referencing to another module source code) can help, but I can't make it work (if it's possible). Here are some similar questions, not sure they can help:
inherit a non gwt module
Inherit external java source in GWT project (similar concept)
Thanks.
(For simplicity, let's assume that app and fx have no external dependencies)
I've investigated the problem deeper, and the general solution is:
Supply the dependencies source code to the dependency repository using the maven-source-plugin plugin. This step is a must because GWT compiles the dependency source code rather than using JAR.
Define a regular GWT module with inherit elements to make dependencies.
Compile the target application using gwt-maven-plugin with the compileSourcesArtifacts configuration option set to match the dependencies.
See more at http://mojo.codehaus.org/gwt-maven-plugin/user-guide/library.html

CQ5 - Separate out a servlet's business logic into a standalone bundle

I am new to java, osgi, bundles, cq5 console etc..
Can someone please point me to a tutorial or a starting point from where I can learn how to do what I am trying to achieve.
Basically we have common search functionality in 3-4 CQ5 websites, all of which reside on a single cq instance. This same functionality is implemented in all websites as a servlet and is called from client side using javascript. Redundant code....
We would like to:
a) take this servlet's code out from all the websiteName-core bundles where it resides repeatedly as of now.
b) create a single separate standalone installable OSGI bundle which only contains a servlet.
Then we would like to call this single separated out bundle from all our CQ5 websites's client side.
Aprt from code redundancy, we wish to make this common search bundle shippable so that other development teams can use it in their projects by just installing it in their console and calling the servlet.
Long story short. I want to create an OSGI bundle that has a servlet.
I wish to have an understanding of the whole game here and would prefer to get a tutorial link that explains it from start to end.
You can start by turning the search code into a separate maven multi module project.The archetype and instructions for creating one can be found on adobe's documentation site (link)
The maven multimodule project will have two module's Bundle and content. Bundle will hold all the servlets, OSGI services and back-end stuff. The content module will have all the UI and authoring related stuff like templates and components. It maps to the repository on the CQ server. The UI nodes are serialized and stored on flat file systems as XML documents.
Since it is a maven project on it's own, it's dependencies will be self contained. In the bundle module add the search servlet and all the required classes. The compiled package of this project will be shippable.
As long as the package is installed in the server, any other website will be able to make calls to it.
Servlets in sling are implemented as OSGI services of javax.servlet.Servlet class. Any exported service of the Servlet class will be recognized by the sling servlet resolver, You can get more details of it at this link
Sharath Madappa's answer is correct if you want to create a set of related bundles and distribute them as a CQ content package.
If you just want to create a single bundle to package some OSGi services (including servlets) you just need to build the bundle jar with the required metadata. The Apache Sling GET servlets bundle is a good example of that.

What's the difference between Eclipse Packages and Plug-ins?

In Dependencies tab, I have a choice between plug-ins and packages.
What's the difference between them? For org.eclipse.compare, I have it in imported package and also in plug-ins.
I find the jar file in plugins directory, but I don't know where the package file of org.eclipse.compare is located.
In the export menu, it seems like that there seems to be only exporting to jar, not exporting a plugin or packages. How can I export packages?
ADDED
Based on this post - How to import a package from Eclipse? and shiplu's answer. This is what I came to understand. Please correct me if I'm wrong.
In eclipse, when I use come external class, I can use Quick-Assistant or Organize imports (Ctrl-Shift-O) to resolve the reference. Eclipse adds the package that contains the class in Imported Packages for the project that I'm working on. A package can contain multiple classes (types). Eclipse understands what plugin contains the package, and resolve the reference issues.
A plug-in (jar file) can contain multiple packages. By specifying a required plug-ins in the dependencies tab, we can reference all the packages (and classes in the packages) for all the java projects in the eclipse IDE.
And from my experience, I had to add all the dependencies in order to make headless RCP standalone (http://prosseek.blogspot.com/2012/12/headless-rcp-standalone.html).
An Eclipse plug-in is basically an OSGi bundle with additional plugin.xml file which Eclipse IDE understands and interprets.
So the answer to your question lies in the OSGi specification and the OSGi programming model, since, very simply put, Eclipse is an Application running on implementation of OSGi called Equinox.
OSGi is all about having modular applications and so it defines several levels of modularity.
One such level is a bundle-level (module-level) modularity and more fine grained level is the package level modularity.
So you can have your OSGi application (a set of bundles; eclipse is just that) which consists of db-bundle (which provides data store services), app-domain-bundle (which provides your application domain services) and remote-bundle (which exposes to the web your application via REST for example).
And then you say remote-bundle depends on domain-bundle which depends on db-bundle.
Which is all good, but cripples the inherent modularity OSGi provides, because you are basically restricting your application to specific implementations of db-bundle and remote-bundle i.e. to specific implementations of the services they provide.
Instead, you can establish the above dependencies not between bundles but between packages i.e. establish a service-level dependencies.
Then you say domain-bundle requires dbstore.service package to run, it doesn't care which bundle provides it it just needs an instance of this service to be able to work. So you can have multiple bundles providing implementations of the dbstore.service, and the domain-bundle can pick and choose at runtime what service to use.
It is really hard to explain OSGi concepts in just a several sentences, I'd really suggest you dig around the web on this and maybe even have a look at the OSGi specification.
Another way to explain it is to say that bundle/plug-in is a jar file with specific structure and metadata descriptors (MANIFEST.MF and plugin.xml), which describe its contents in Java language concepts - which java packages and services this specific jar contains and will expose to the OSGi runtime so that they can be consumed by other bundles. I.e. the bundle is the physical deployable entity while the descriptors are metadata about what actually is being deployed.
EDIT:
Package or Service-level dependencies also have some drawbacks, as Lii points out in the comments below, the main one being that it adds complexity and dynamics to the dependency model. Have a look at her or his comment below - it is worth reading!
You use Imported Packages when you want to use a specific package but do not care which plugin provides it. OSGI will choose one for you.
Eclipse plugins is something like extension to the IDE itself. But imported packages are actually packages that you'll use in your current project.
One is for development IDE another is for the project you are coding.