Search This Blog

Wednesday 31 May 2017

Sling models and WCMUsePojo



  • You should use one or the other - if you use WCMUse/WCMUsePojo - then do not use SLing Models. If you want to use SLing Models - then do not use WCMUse/WCMUsePojo.
  • Both provide the same functionality so no use of using both.
  • WCMUse is deprecated in 6.1. Use WCMUsePojo instead.

Now let’s look at the implementation for this, you have 5(!) options:
  1.  Class that implements the Use interface (deprecated)
  2.  Class that extends WCMUsePojo class
  3.  Class that is adaptable from Resource (resource.adaptTo(YourClass))
  4.  Class that is adaptable from Request (request.adaptTo(YourClass))
  5.  Sling Models
Both 3,4 are usefull when you implement AdapterFactory interface. These 2 can be ignored.


Inject annotation issue in Sling models AEM 6.2

Read here - http://aemconcepts.blogspot.com/2017/07/sling-model-inject-annotation-issue-in.html

Sling models


  • Sling models can be created using model annotation which automatically adapts your request or resource.
  • Doesn’t provide any activate method. Activate method is treated just like another method.
  • Method have @PostConstruct annotation does not need to be called using a use object. It gets called automatically after all injections are done. Once you edit and save dialog injections happen again hence method with this annotation is called again.
  • Style object currentStyle is also only available through the SlingHttpServletRequest as an injection and not thru adapting to a resource. But in adaptable from resource we can get it by adapting resource.

Available injectors for sling models.


 Inject resource resolver

    @Inject
    private ResourceResolver resourceResolver;


 @named annotation

Injects are injected as instance variables with same name as the property. Both if you want different property name and instance name then this annotation can be used. For example
      /** The news filter tags. */
      @Inject
      @Named("newsfiltertags")
      private String[] newsFilterTags;

This inject newsfiltertags property value in newsFilterTags instance variable.


Sling model adaptable from request

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class MegaMenuModel {…}

Retrieve resource


To retrieve resource.

  1.          request.getResource();
  2.          Inject
      @Source("script-bindings")    [optional]  private Resource resource;


 To inject Style for design

      @Inject
      private Style currentStyle;


Sling model adaptable from resource


@Model
(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

public
class LoginSplashScreenModel {…}


Get Style object to retrieve from design


TagManager = resourceResolver.adaptTo(TagManager.class);
designer = this.resourceResolver.adaptTo(Designer.class);
if (designer != null) {
      style = designer.getStyle(resource);
}
                 
if (StringUtils.isEmpty(viewAllTitle)) {
      viewAllTitle = style.get("viewalltitle", String.class);
}

Passing Parameters from slightly to sling models.

To show the full range of possibilities, let’s also pass a parameter, so the content of the data-sly-use attribute must be changed to an expression with an option:
<div data-sly-use.myComponent="${'com.myproject.MyComponent' @ param1='one', param2='two'}">
    ${myComponent.calculatedValue}
</div>



WCMUsePojo/WCMUse

·       Provides convenience method activate() which is called from wcmusepojo.init() once all injections are done. Implement this method to perform post initialization tasks.

·      Method activate does not need to be called using a use object. It gets called automatically after all injections are done.

@Override
activate(){..}

Thursday 18 May 2017

Common Issues in Debugger


Debugger keeps popping up with following stack trace


ThreadExpiringThreadPool(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: not available
ThreadPoolExecutor$Worker.run() line: not available
Thread.run() line: not available  

Solution
Configuring the behavior of Eclipse is straightforward:

Go to Window > Preferences > Java > Debug and uncheck Suspend execution on uncaught exceptions.


Source and Reference






Debugger doesn’t work



 

All threads not started hence debugging wont work.

Solution

Increase max heap size ie -Xmx param.


Remote debugging in aem


In remote debugging.

1.      Aem forces the jvm to fork a process.

2.      UseSplitVerifier is required for java 7. (Even to start cq normally w/o debug mode.)



Modify start.bat (or create a debug.bat by modifying start.bat)


if not defined CQ_JVM_OPTS set CQ_JVM_OPTS=-Xmx1024m -XX:MaxPermSize=512M -XX:-UseSplitVerifier -Djava.awt.headless=true
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=30302

OR

if not defined CQ_JVM_OPTS set CQ_JVM_OPTS=-Xmx1024m -XX:MaxPermSize=512M -XX:-UseSplitVerifier -Djava.awt.headless=true
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=30303

OR

start "CQ" cmd.exe /K java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=30302,suspend=n %CQ_JVM_OPTS% -jar %CQ_JARFILE% %START_OPTS%



Or Run from CMD (from the directory where jar is present)


java -jar cq-publish-p4503.jar -XX:MaxPermSize=512m -Xmx1024m
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=30305
-Dsling.run.modes=publish

OR

java -jar cq-publish-p4503.jar -XX:MaxPermSize=512m -Xmx1024m
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=30303
-Dsling.run.modes=publish


For Common Issues in Debugger



Wednesday 17 May 2017

JVM parameters in Java



On the basis of how we specify JVM option it can be divided into two parts, JVM Options which starts with –X and those which starts with -XX:

1)       JVM Options that begin with -X are non-standard (thy are not guaranteed to be supported on all JVM implementations), and are subject to change without notice in subsequent releases of the JDK.

2)       JVM Options or parameters which are specified with -XX are not stable and are not recommended for casual use. These options are subject to change without notice also.




 -Xmx


The flag Xmx specifies the maximum memory allocation pool for a Java Virtual Machine (JVM), while Xms specifies the initial memory allocation pool. A common use for these flags is when you encounter a java.lang.OutOfMemoryError.

 -Xms        set initial Java heap size
 -Xmx        set maximum Java heap size
      -Xss>         set java thread stack size

-XX:MaxPermSize


are used to set size for Permanent Generation.

Permanent Generation: The Permanent Generation is where class files are kept and never deallocated as the name suggests. These are the result of compiled classes and jsp pages. If this space is full, it triggers a Full Garbage Collection. If the Full Garbage Collection cannot clean out old unreferenced classes and there is no room left to expand the Permanent Space, an Out‐of‐ Memory error (OOME) is thrown and the JVM will crash


agentlib:jdwp 


Sun's VM implementations require command line options to load the JDWP agent for debugging.

From 5.0 onwards the
 -agentlib:jdwp option is used to load and specify options to the JDWP agent.

For releases prior to 5.0, the -Xdebug and -Xrunjdwp options are used
 

The -agentlib:jdwp and -Xrunjdwp option can be further qualified with sub-options. The sub-options are specified as follows:
    -agentlib:jdwp=<name1>[=<value1>],<name2>[=<value2>]...
or
   -Xdebug -Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...


Transports


A JPDA Transport is a method of communication between a debugger and the virtual machine that is being debugged (hereafter the target VM).  The communication is connection oriented - one side acts as a server, listening for a connection. The other side acts as a client and connects to the server. JPDA allows either the debugger application or the target VM to act as the server. 


  1. Socket Transport
The JPDA reference implementation provides a socket transport for the Solaris, Linux, and Microsoft Windows platforms. The socket transport uses a TCP/IP connection between the debugger application and the target VM. With the socket transport, the debugger application and target VM can reside either on the same machine or on different machines.
The socket transport is identified through a unique string, dt_socket.


  1. Shared Memory Transport
In addition to the socket transport, the JPDA reference implementation provides a shared memory transport on the Microsoft Windows platform. The shared memory transport uses a shared memory region to exchange JDWP packets between the debugger application and the target VM. With the shared memory transport, the debugger application and target VM must reside on the same machine.
The shared memory transport is identified through a unique string, dt_shmem.

Server
The option server=y opens a socket and listens for incoming debugger requests(cq acts as server).
With server=n the debugged application will try to connect actively to a debugger and run therefore as a client.


Suspend

In JVM DEBUG parameters there is a parameter called "suspend" which takes the value as "y" or "n". so if you want to debug the process from the start set this parameter as "suspend=y" and your Java application will wait until Eclipse remotely connects to it. Otherwise, if you want to run your program and later want eclipse to be connected that set this as "suspend=n" so your java application will run normally and after eclipse remotely connected to it, it will stop on breakpoints. (default  value suspend=y if not specified)


Source and References

http://javarevisited.blogspot.in/2011/11/hotspot-jvm-options-java-examples.html


Tuesday 9 May 2017

Read and write to parent node from component dialog


Suppose you have a included or a dragged and drop component on a page and you want the properties configured in the component dialog to be saved in the properties of the page ie jcrcontent as some other component also might want to use the same property.

Suppose it’s a drag and drop component then the content hierarchy would be like

<page>/jcrcontent/par/<component>


Write


Now to save at jcrcontent level we need to move two levels up. So, in the component dialog the property ‘name’ should be


This will save the property at jcrcontent level.



Read


Now once you save the values and again open the component dialog it will not show the configured property value even though they are saved correctly. This is because we have only told the dialog where to save properties not from where to pick it. So by default its trying to pick from the component node itself.

For this we need a beforeloadcontent listener which is run before the dialog is loaded.
Listener node needs to be created below the xtype property node in the dialog.




function(field, record, path) {
    var targetField = field.getName().replace('./', '');
    var pathParts = path.split('/');
    pathParts.pop(); //use this line to travel to hierarchy where you original property has been set
    pathParts.pop();
    var jcrContentPath = pathParts.join('/'); // once you reach to that path in this case page jcr:content get the path
    var response = CQ.utils.HTTP.get(jcrContentPath + '.json'); // make get query to this path and retrieve response
    eval('var data =' + response.responseText); //data will have all the property value associated
    var originalPropName = "contentAuthors";
    if (data[originalPropName] != undefined) {
        var originalPropVal = data[originalPropName];
        this.setValue(originalPropVal); //setting the value to corresponding component attribute
        return false; //dont forget to return false to set the value and stop further processing
    }
}

Important to note in the listener is that we need pop as many times as the level we need to move up. So here its 2. Also, take care of the property name.

Suppose it’s an included component we can use property name as name="../contentAuthors" and use the parthParts.pop() in listener only once.