Saturday, October 21, 2017

Test AEM Servlet using Postman - 403 Forbidden error


Issue: Created AEM servlet and testing post request from Postman returns 403 - Forbidden Error.


Steps:

2. Search for 'Apache Sling Referrer Filter'
3. Remove POST method from the filter. 
4. Select “Allow Empty” and 'Save'
5. Again search for 'Adobe Granite CSRF Filter' 
6. Add your servlet path in 'Excluded Paths' list.

Now you can call your POST method anywhere.

Hope it works..

Monday, June 1, 2015

AEM 6 MongoDB: Is it time to migrate to Mogodb?



Based on findings, there are still a lot of issues with mongodb as persistence layer for AEM 6. Few points to be noted:


  1. "Sharding" feature of Mongodb is not supported by AEM yet. So horizontal scaling of Mongodb Primary is not possible yet to use with AEM.
  2. Performance of AEM with mongodb is not as good as compared to TarMK. 
  3. TarMK is the best practice still by Adobe support team. AEM replication can be used to sync content from one data center to other to have DR center ready with TarMK and publish content to multiple publish instances.

References:
http://docs.adobe.com/docs/en/aem/6-0/deploy/recommended-deploys.html
http://docs.adobe.com/docs/en/aem/6-0/deploy/upgrade/microkernels-in-aem-6-0.html
http://docs.mongodb.org/manual/administration/sharded-clusters/


Thursday, April 23, 2015

How to take Thread Dump in windows

There are different ways to take thread dumps. 

Procedure 1:  Use Powershell
Procedure 2:  Use jstack

Powershell:

1. Download "PsExec.exe" and save it.

2. Go to Start->Run and type "powershell",


3. Powershell will be opened.

4. Navigate to the path where the "PsExec.exe" exist and type following command
    “PsExec.exe -s jstack PID > Dump.txt”

5. Dump file will be created.

Procedure 2:
Create sample Threaddump.java class  and run.


public class Threaddump {

/**
* @param args
*/
public static void main(String[] args) {
int count =10;
ExecCommand myExc= new ExecCommand();
while(count >0)
{
myExc.ExecCommand("jstack -F 6072 > jstack."+count);
Thread.sleep(5000);
count--;
}
}

}

Note: Change PID and file paths.
===========================================================================
 ExecCommand class

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class ExecCommand {
private Semaphore outputSem;
private String output;
private Semaphore errorSem;
private String error;
private Process p;
private int exitValue;

private class InputWriter extends Thread {
 private String input;


 public InputWriter(String input) {
  this.input = input;
 }

 public void run() {
  PrintWriter pw = new PrintWriter(p.getOutputStream());
  pw.println(input);
  pw.flush();
 }
}

private class OutputReader extends Thread {
 public OutputReader() {
  try {
  outputSem = new Semaphore(1);
  outputSem.acquire();
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }

 public void run() {
  try {
  StringBuffer readBuffer = new StringBuffer();
  BufferedReader isr = new BufferedReader(new InputStreamReader(p
   .getInputStream()));
  String buff = new String();
  while ((buff = isr.readLine()) != null) {
   readBuffer.append(buff);
   System.out.println(buff);
  }
  output = readBuffer.toString();
  outputSem.release();
  } catch (IOException e) {
  e.printStackTrace();
  }
 }
}

private class ErrorReader extends Thread {
 public ErrorReader() {
  try {
  errorSem = new Semaphore(1);
  errorSem.acquire();
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }

 public void run() {
  try {
  StringBuffer readBuffer = new StringBuffer();
  BufferedReader isr = new BufferedReader(new InputStreamReader(p
   .getErrorStream()));
  String buff = new String();
  while ((buff = isr.readLine()) != null) {
   readBuffer.append(buff);
  }
  error = readBuffer.toString();
  errorSem.release();
  } catch (IOException e) {
  e.printStackTrace();
  }
  if (error.length() > 0)
  System.out.println(error);
 }
}

public ExecCommand(String command, String input) {
 try {
  p = Runtime.getRuntime().exec(makeArray(command));
  new InputWriter(input).start();
  new OutputReader().start();
  new ErrorReader().start();
  p.waitFor();
 } catch (IOException e) {
  e.printStackTrace();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
}

public ExecCommand(String command) {
 try {
  p = Runtime.getRuntime().exec(makeArray(command));
  new OutputReader().start();
  new ErrorReader().start();
  p.waitFor();
  exitValue=p.exitValue();
 } catch (IOException e) {
  e.printStackTrace();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
}

public int getExitValue(){
return exitValue;
}
public String getOutput() {
 try {
  outputSem.acquire();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 String value = output;
 outputSem.release();
 return value;
}

public String getError() {
 try {
  errorSem.acquire();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 String value = error;
 errorSem.release();
 return value;
}

private String[] makeArray(String command) {
 ArrayList<String> commandArray = new ArrayList<String>();
 String buff = "";
 boolean lookForEnd = false;
 for (int i = 0; i < command.length(); i++) {
  if (lookForEnd) {
  if (command.charAt(i) == '\"') {
   if (buff.length() > 0)
   commandArray.add(buff);
   buff = "";
   lookForEnd = false;
  } else {
   buff += command.charAt(i);
  }
  } else {
  if (command.charAt(i) == '\"') {
   lookForEnd = true;
  } else if (command.charAt(i) == ' ') {
   if (buff.length() > 0)
   commandArray.add(buff);
   buff = "";
  } else {
   buff += command.charAt(i);
  }
  }
 }
 if (buff.length() > 0)
  commandArray.add(buff);

 String[] array = new String[commandArray.size()];
 for (int i = 0; i < commandArray.size(); i++) {
  array[i] = commandArray.get(i);
 }

 return array;
}
}









Wednesday, April 8, 2015

Better to disable XML rendering to prevent your source code

It would be a better to disable xml rendering to prevent your source code /apps being stolen:
Ref:
http://crxdelight.com/2012/03/26/preventing-your-source-code-in-apps-from-being-stolen/

Saturday, July 5, 2014

How to enable logging for JSP pages?

JSPs are compiled into a package called org.apache.jsp with the script path converted to further package parts.

Example: 











You can configure below log name to enable logging for title.jsp

log Name:   org.apache.jsp.apps.demo.components


Friday, July 4, 2014

What is Replication in CQ5 & the process.

Replication is the mechanism used to:

Publish (activate) content from an author to publish environment.
Explicitly flush content from the Dispatcher cache.
Return user input (eg, form input) from publish environment to the author environment (under control of the author environment)

REPLICATION PROCESS:

1)    First, the author requests that certain content to be published (activated).
2)    The request is passed to the appropriate default replication agent.
3)    Replication agent packages the content and places it in the replication queue.
4)    the content is lifted from the queue and transported to the publish environment using the   configured protocol.
5)    a servlet in the publish environment receives the request and publishes the received content, the default servlet is http://localhost:4502/bin/receive.

Sunday, December 15, 2013

Guidelines - Assets Upload into CQ DAM

Here are the few guidelines suggested by CQ Experts (from google groups):

1. Folder/Asset Naming convention

    a. Is it good a have a folder/Asset name contains underscore ( _ ).

        Eg:  /content/dam/Test/Advanced_buttons

    Is CQ providing any best naming conventions.

2. Assets (Images/pdf/docs whatever)

     a. What is the max size limit of an Asset?

3. What is the max number of Assets that we can upload in a dam folder.

Comments:

1. Yes folders can have underscores. I didn't see any issue till now.

2. Max size limit I am not sure but I injected around 10 to 30 MB size with out any issues.

3. There should not be much issue even if you inject 100 to 150 gigs of assets. we migrated around 130 gigs with out much issues. In terms of number of assets inside a particular folder (Number of nodes at one level) Adobe recommends dont use more than 200 to 250 at one level. If it is more than that front end DAM UI will slows down (still repository doesn't show any issue)

Friday, October 11, 2013

Installing and Starting Adobe Experience Manager as a Windows Service

 

Note:

  1. Your need to login as Administrator or start/run these steps using Run As Administrator command prompt. 
  2. If you don’t follow the above instruction, you will get Access denied error while completing steps.

Steps:

  1. Open the crx-quickstart\opt\helpers\instsrv.bat file in a text editor.
  2. If you are configuring a 64-bit Windows server, replace all instances of prunsrv with one of the following commands, according to your operating system:
    prunsrv_amd64
    prunsrv_ia64
    This command invokes the appropriate script that starts the Windows service daemon in 64-bit Java instead of 32-bit Java. 
  3. To prevent the process from forking into more than one process, increase the maximum heap size and the PermGen JVM parameters. Locate the set jvm_options command and set the value as follows:

    set jvm_options=-XX:MaxPermSize=256M;-Xmx1792m

  4. Open Command Prompt, change the current directory to the crx-quickstart/opt/helpers folder of the AEM installation, and enter the following command to create the service:

    instsrv.bat cq5

    To verify that the service is created, open Services in the Administrative Tools control panel or type start services.msc in Command Prompt. The cq5 service appears in the list.

  5. Start the service by doing one of the following:
    1. In the Services control panel, click cq5 and click Start.
      StartServices
    2. In the command line, type net start cq5
      StartCommandprompt
  6. Windows indicates that the service is running. AEM starts and the prunsrv executable appears in Task Manager.

    prunsrv

  7. Note: The property values in the instsrv.bat file are used when creating the Windows service. If you edit the property values in instsrv.bat, you must uninstall and then re-install the service.

  8. To uninstall the service, either click Stop in the Services control panel or in the command line, navigate to the folder and type instsrv.bat -uninstall cq5. The service gets removed from the list in the Services control panel or from the list in the command line when you type net start.

Ref: http://dev.day.com/docs/en/cq/current/getting_started/download_and_startworking.html#Installing%20and%20Starting%20Adobe%20Experience%20Manager%20as%20a%20Windows%20Service

Sunday, September 15, 2013

How to get Service in JSP?

Below are the two easiest ways to get Service:

1. Using the slingScriptHelper     

<sling:defineObjects />

<%

      ServiceType service = sling.getService(ServiceType.class);

%>

2. Using adaptTo()

adaptTo() method that will translate the object to the class type being passed as the argument.

Example:

Node node = resource.adaptTo(Node.class);

More Info on Adaptors: http://dev.day.com/docs/en/cq/current/developing/sling-adapters.html

Handy URLs–AEM 5.6

URLs

/crx/explorer/index.jsp  - CRX explorer

/crx/de/index.jsp – CRXDE Lite url

/damadmin     - DAM

/libs/cq/search/content/querydebug.html – Query debug tool

/libs/granite/security/content/admin.html – New user manager standalone ui  [5.6 only?]

/libs/cq/contentsync/content/console.html – Content sync console

/system/console/bundles – Felix web admin console

/system/console/jmx/com.adobe.granite.workflow%3Atype%3DMaintenance - Felix web admin console JMX / Workflow maintenance tasks

/system/console/jmx/com.adobe.granite%3Atype%3DRepository - Felix web admin console JMX / Repository maintenance tasks

/system/console/depfinder – This new 5.6 tool will help you figure out what package exports a class and also prints a Maven Dependency for the class.

/libs/granite/ui/content/dumplibs.rebuild.html?rebuild=true – Helpful link for debugging caching problems. Wipes the clientlibs and designs and forces it to rebuild it. Thanks to Mark Ellis for this link.

/system/console/adapters – This link shows you the Adapters are registered in the system. This helps you figure out what you can adaptTo() from resource to resource.

Params

wcmmode=DISABLED - This handy publisher parameter turns off CQ authoring features so you can preview a page cleanly

Thursday, September 5, 2013

How to get Administrative Resource Resolver in jsp?

 

Generic Code to get service from the OSGI service registry:

================================================================

If you are in a JSP Script you can do

<cq:defineObjects />

<%

      ServiceType service = sling.getService(ServiceType.class);

   %>

==================================================================

Get Administrative Resource Resolver :

<%!

      /**
           @Parms: ResourceResolverFactory
          returns ResourceResolver , Admin resource resolver will be return
    */
    public ResourceResolver getRR(ResourceResolverFactory resolverFactory)
    {

        ResourceResolver rr=null;
        try{

            rr= resolverFactory.getAdministrativeResourceResolver(null);
        }catch(Exception e)
        {
            System.out.println("RRF Exception:"+e.getMessage());
        }
        return rr;
    }

%>

<%

//Get ResourceResolverFactory service from OSGI service Registry

org.apache.sling.api.resource.ResourceResolverFactory  rrFactory = sling.getService(org.apache.sling.api.resource.ResourceResolverFactory.class);

          Resource r = getRR(rrFactory);  

%>

Wednesday, July 31, 2013

How to get Resource?

In OSGI Service/Compoment
You can access a resource through the JcrResourceResolverFactory service:

@Reference
private SlingRepository repository;

@Reference
private JcrResourceResolverFactory resolverFactory;

public void myMethod() {
    Session adminSession = null;   
    try {       
         String resourcePath = "path/to/resource";       
         adminSession = repository.loginAdministrative(null);       
         ResourceResolver resourceResolver = resolverFactory.getResourceResolver(adminSession);       
         Resource res = resourceResolver.getResource(resourcePath);    
    } catch (RepositoryException e) {
        log.error("RepositoryException: " + e);   
    } finally {       
        if (adminSession != null && adminSession.isLive()) {
           adminSession.logout();          
                adminSession = null;       
         }    
     }
}
In JSP

<sling:defineObjects>
<%
String resourcePath = "path/to/resource";
Resource res = resourceResolver.getResource(resourcePath);
%>
 

Monday, July 29, 2013

What is the notation of translation site to be created? (Managing Different Language Versions of a Website)

1. In the Websites tab, in the left pane, select the site.

2. Add a new language branch to the site:

    a. Click New..

    b. In the dialog, specify the Title and the Name.

        The Name needs to have the following format:
<language-code> or <language-code>_<country-code>
        - the supported language code is lower-case, two-letter code as defined by ISO-639-1
        - the supported country code is lower-case or upper-case, two-letter code as defined by ISO 3166
Examples: en, en_US, en_us, en_GB, en_gb.

        Select the Template and click Create.   

file

3. In the Websites tab, in the left pane, select the site.

4. In the Tools menu, select Language Copy.

file

5. The Language Copy dialog opens. It displays a matrix of the language versions available for individual pages. An x in a language column means that the page is available within the language tree.

file

6. To copy an existing page or page tree to a specific language first select the appropriate empty cell. Then click the arrow and select the type of copy in the drop-down menu.

Type of language copy
Description

auto
Uses the behavior from parent pages

ignore
Cancels the copy for this page and its children

<language>+ (e.g. French+)
Copies the page and all its children from that language

<language> (e.g. French)
Copies only the page from that language

file

7. Click OK to close the dialog.

8. In the next dialog, click Yes to confirm the copy.

Wednesday, July 24, 2013

How to create AEM Groups package including ACLs?

Download the custom package from : http://www.wemblog.com/2011/11/how-to-create-package-based-on-xpath-in.html
1) Install package using package manager
2) go to <host>:<port>/apps/tools/components/createPackage/run.html
3) Give your Xpath in xpath value
4) You can also add comma separate exclude path that you don't want to add to package.
5) Click on Create config package
6) Now Download the package and also be saved under /etc/packages/CQSupportTool
For example if you have to create package of all ACL to migrate from one CQ instance to another you can use xpath query for package as //element(*,rep:ACL)

Example:

Ref: http://www.wemblog.com/2011/11/how-to-create-package-based-on-xpath-in.html

Wednesday, July 10, 2013

How can we hide the CMS Console Buttons

 

How can we hide some of the CMS consoles / tabs (like the Site Admin, DAM Admin, Tools, Security, Workflow and Tagging) via permissions?

Answer:  Uncheck the READ permission for groups/users on the corresponding console node.

Ref: http://helpx.adobe.com/cq/kb/CQ53HowToHideCQNavigationButtons.html

Monday, July 8, 2013

Syntax while executing Shell Script in windows

Error Type:

./script.sh: line 1: syntax error near unexpected token '$'do\r''

Or ...

./script.sh: line 1: $'\r': command not found

Solution:  http://www.jwgoerlich.us/blogengine/post/2007/06/08/Tip-Bash-scripting-in-Cygwin-without-5cr-syntax-errors.aspx

How to take Thread Dumps from a JVM

Step 1: Get the PID of your java process

The java JDK ships with the jps command which lists all java process ids.

You can run this command like this: jps –l

8112
1396 sun.tools.jps.Jps
3576 crx-quickstart\app\cq-quickstart-5.6.0-standalone.jar

Step 2 : Request a Thread Dump from the JVM

In windows:

1. Install cygwin to run shell script

2. set path to the environment variable list.

3. Add following script in the <name>.sh

#!/bin/bash
if [ $# -eq 0 ]; then
    echo >&2 "Usage: jstackSeries <pid> <run_user> [ <count> [ <delay> ] ]"
    echo >&2 "    Defaults: count = 10, delay = 0.5 (seconds)"
    exit 1
fi
pid=$1          # required
user=$2         # required
count=${3:-10}  # defaults to 10 times
delay=${4:-0.5} # defaults to 0.5 seconds
while [ $count -gt 0 ]
do
    jstack -F $pid >jstack.$pid.$(date +%H%M%S.%N)
    sleep $delay
    count=`expr $count - 1`
    echo -n "."
done

          4. You can run this shell script like:

               sh  <name>.sh <Process Id of AEM> <Intervals> <No.of Threads>

              Eg:  sh TrheadDump.sh  4321 10 5

              Result: It takes 5 thread dumps at an intervals of 10 sec.

Note: Running CQ on UNIX ?

           Reference: http://helpx.adobe.com/cq/kb/TakeThreadDump.html 

 

Friday, June 28, 2013

How to check whether the payload is subjected to the workflow or not?

You can use “com.adobe.granite.workflow.status.WorkflowStatus” API to check the WF status of the payload.

      Eg:

WorkflowStatus wfState = <payload object>.adaptTo(WorkflowStatus.class);

          boolean status=false;
          status = wfState.isInRunningWorkflow(true);