Show Menu
THEMEN×

Grundlegendes zu benutzerspezifischen Regeln für die Code-Qualität

Auf dieser Seite werden die benutzerspezifischen Regeln für die Code-Qualität beschrieben, die von Cloud Manager ausgeführt werden und auf bewährten Verfahren des AEM Engineering basieren.
Die hier bereitgestellten Codebeispiele dienen nur Veranschaulichungszwecken.

SonarQube-Regeln

Im folgenden Abschnitt werden die SonarQube-Regeln hervorgehoben:

Verwenden Sie keine potenziell gefährlichen Funktionen.

Schlüssel : CQRules:CWE-676
Typ : Sicherheitslücke
Schweregrad : Hoch
Seit : Version 2018.4.0
Die Methoden Thread.stop() und Thread.interrupt() können schwer reproduzierbare Probleme und in einigen Fällen Sicherheitslücken verursachen. Daher sollte deren Verwendung sorgfältig überwacht und validiert werden. Im Allgemeinen ist die Nachrichtenübergabe eine sicherere Möglichkeit, ähnliche Ziele zu erreichen.

Nicht konformer Code

public class DontDoThis implements Runnable {
  private Thread thread;
 
  public void start() {
    thread = new Thread(this);
    thread.start();
  }
 
  public void stop() {
    thread.stop();  // UNSAFE!
  }
 
  public void run() {
    while (true) {
        somethingWhichTakesAWhileToDo();
    }
  }
}

Konformer Code

public class DoThis implements Runnable {
  private Thread thread;
  private boolean keepGoing = true;
 
  public void start() {
    thread = new Thread(this);
    thread.start();
  }
 
  public void stop() {
    keepGoing = false;
  }
 
  public void run() {
    while (this.keepGoing) {
        somethingWhichTakesAWhileToDo();
    }
  }
}

Verwenden Sie keine Formatzeichenfolgen, die extern gesteuert werden können.

Schlüssel : CQRules:CWE-134
Typ : Sicherheitslücke
Schweregrad : Hoch
Seit : Version 2018.4.0
Durch die Verwendung einer Formatzeichenfolge aus einer externen Quelle (z. B. einem Abfrageparameter oder benutzergenerierten Inhalten) kann eine Anwendung für Denial-of-Service-Angriffe anfällig werden. In einigen Situationen wird eine Formatzeichenfolge extern kontrolliert. In diesem Fall darf sie jedoch nur aus vertrauenswürdigen Quellen verwendet werden.

Nicht konformer Code

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) {
  String messageFormat = request.getParameter("messageFormat");
  request.getResource().getValueMap().put("some property", String.format(messageFormat, "some text"));
  response.sendStatus(HttpServletResponse.SC_OK);
}

HTTP-Anfragen sollten immer Zeitüberschreitungswerte für Sockets und Verbindungen enthalten.

Schlüssel : CQRules:ConnectionTimeoutMechanism
Typ : Fehler
Schweregrad : Kritisch
Seit : Version 2018.6.0
Beim Ausführen von HTTP-Anfragen aus einer AEM-Anwendung muss unbedingt sichergestellt sein, dass korrekte Zeitüberschreitungswerte konfiguriert werden, um unnötige Thread-Nutzung zu vermeiden. Leider sind im Java-Standard-HTTP-Client (java.net.HttpUrlConnection) und dem häufig verwendeten Client für Apache-HTTP-Komponenten standardmäßig keine Zeitüberschreitungen festgelegt, sodass diese explizit festgelegt werden müssen. Als Best Practice gilt, diese Zeitüberschreitungen bei maximal 60 Sekunden zu definieren.

Nicht konformer Code

@Reference
private HttpClientBuilderFactory httpClientBuilderFactory;
 
public void dontDoThis() {
  HttpClientBuilder builder = httpClientBuilderFactory.newBuilder();
  HttpClient httpClient = builder.build();

  // do something with the client
}

public void dontDoThisEither() {
  URL url = new URL("http://www.google.com");
  URLConnection urlConnection = url.openConnection();
 
  BufferedReader in = new BufferedReader(new InputStreamReader(
    urlConnection.getInputStream()));
 
  String inputLine;
  while ((inputLine = in.readLine()) != null) {
    logger.info(inputLine);
  }
 
  in.close();
}

Konformer Code

@Reference
private HttpClientBuilderFactory httpClientBuilderFactory;
 
public void doThis() {
  HttpClientBuilder builder = httpClientBuilderFactory.newBuilder();
  RequestConfig requestConfig = RequestConfig.custom()
    .setConnectTimeout(5000)
    .setSocketTimeout(5000)
    .build();
  builder.setDefaultRequestConfig(requestConfig);
 
  HttpClient httpClient = builder.build();
   
  // do something with the client
}

public void orDoThis() {
  URL url = new URL("http://www.google.com");
  URLConnection urlConnection = url.openConnection();
  urlConnection.setConnectTimeout(5000);
  urlConnection.setReadTimeout(5000);
 
  BufferedReader in = new BufferedReader(new InputStreamReader(
    urlConnection.getInputStream()));
 
  String inputLine;
  while ((inputLine = in.readLine()) != null) {
    logger.info(inputLine);
  }
 
  in.close();
}

Produkt-APIs, die mit @ProviderType kommentiert wurden, sollten von Kunden nicht implementiert oder erweitert werden.

Schlüssel : CQBP-84, CQBP-84-dependencies
Typ : Fehler
Schweregrad : Kritisch
Seit : Version 2018.7.0
Die AEM-API enthält Java-Schnittstellen und -Klassen, die durch benutzerdefinierten Code lediglich verwendet, aber nicht implementiert werden sollen. Zum Beispiel ist die Schnittstelle com.day.cq.wcm.api.Page nur für die Implementierung durch AEM ausgelegt.
Wenn zu diesen Schnittstellen neue Methoden hinzugefügt werden, wirken sich diese zusätzlichen Methoden nicht auf den vorhandenen Code aus, der diese Schnittstellen verwendet. Daher wird das Hinzufügen neuer Methoden zu diesen Schnittstellen als abwärtskompatibel betrachtet. Wenn jedoch benutzerdefinierter Code eine dieser Schnittstellen implementiert , führt dieser benutzerspezifische Code ein Abwärtskompatibilitätsrisiko für den Kunden ein.
Schnittstellen (und Klassen), die nur von AEM implementiert werden sollen, werden mit org.osgi.annotation.versioning.ProviderType (oder in einigen Fällen mit einer veralteten Anmerkung aQute.bnd.annotation.ProviderType ) kommentiert. Diese Regel identifiziert die Fälle, in denen eine solche Schnittstelle durch benutzerdefinierten Code implementiert wird (oder eine Klasse erweitert wird).

Nicht konformer Code

import com.day.cq.wcm.api.Page;

public class DontDoThis implements Page {
// implementation here
}

ResourceResolver-Objekte sollten immer geschlossen werden.

Schlüssel : CQRules:CQBP-72
Typ : Code Smell
Schweregrad : Hoch
Seit : Version 2018.4.0
ResourceResolver-Objekte, die aus ResourceResolverFactory abgerufen werden, verbrauchen Systemressourcen. Obwohl es Möglichkeiten gibt, mit denen diese Ressourcen gelöscht werden, wenn ein ResourceResolver nicht mehr verwendet wird, ist es effizienter, alle offenen ResourceResolver-Objekte explizit durch Aufruf der close()-Methode zu schließen.
Ein verbreiteter Irrtum besagt, dass ResourceResolver-Objekte, die mit einer bestehenden JCR-Sitzung erstellt wurden, nicht explizit geschlossen werden sollten, da dies sonst die zugrunde liegende JCR-Sitzung schließt. Das ist nicht der Fall: Unabhängig davon, wie ein ResourceResolver geöffnet wurde, sollte er geschlossen werden, wenn er nicht mehr verwendet wird. Da ResourceResolver die Closeable-Schnittstelle implementiert, kann auch die Syntax „try-with-resources“ verwendet werden, anstatt explizit „close()“ aufzurufen.

Nicht konformer Code

public void dontDoThis(Session session) throws Exception {
  ResourceResolver resolver = factory.getResourceResolver(Collections.singletonMap("user.jcr.session", (Object)session));
  // do some stuff with the resolver
}

Konformer Code

public void doThis(Session session) throws Exception {
  ResourceResolver resolver = null;
  try {
    resolver = factory.getResourceResolver(Collections.singletonMap("user.jcr.session", (Object)session));
    // do something with the resolver
  } finally {
    if (resolver != null) {
      resolver.close();
    }
  }
}

public void orDoThis(Session session) throws Exception {
  try (ResourceResolver resolver = factory.getResourceResolver(Collections.singletonMap("user.jcr.session", (Object) session))){
    // do something with the resolver
  }
}

Verwenden Sie keine Sling-Servlet-Pfade zum Registrieren von Servlets.

Schlüssel : CQRules:CQBP-75
Typ : Code Smell
Schweregrad : Hoch
Seit : Version 2018.4.0
Wie in der Sling-Dokumentation beschrieben, sollten Servlets nicht über Pfade verknüpft werden. Pfadgebundene Servlets können keine standardmäßigen JCR-Zugriffssteuerungselemente verwenden, sodass besonders strenge Sicherheitsmaßnahmen erforderlich sind. Statt pfadgebundene Servlets zu verwenden, wird empfohlen, Knoten im Repository zu erstellen und Servlets nach Ressourcentyp zu registrieren.

Nicht konformer Code

@Component(property = {
  "sling.servlet.paths=/apps/myco/endpoint"
})
public class DontDoThis extends SlingAllMethodsServlet {
 // implementation
}

Ausnahmefehler sollten protokolliert oder ausgegeben werden, aber nicht beides.

Schlüssel : CQRules:CQBP-44---CatchAndEitherLogOrThrow
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Im Allgemeinen sollte eine Ausnahme genau einmal protokolliert werden. Die mehrfache Protokollierung von Ausnahmen kann verwirren, da unklar ist, wie oft eine Ausnahme aufgetreten ist. Dies wird vor allem dadurch verursacht, dass eine erfasste Ausnahme sowohl protokolliert als auch ausgegeben wird.

Nicht konformer Code

public void dontDoThis() throws Exception {
  try {
    someOperation();
  } catch (Exception e) {
    logger.error("something went wrong", e);
    throw e;
  }
}

Konformer Code

public void doThis() {
  try {
    someOperation();
  } catch (Exception e) {
    logger.error("something went wrong", e);
  }
}

public void orDoThis() throws MyCustomException {
  try {
    someOperation();
  } catch (Exception e) {
    throw new MyCustomException(e);
  }
}

Vermeiden Sie Protokollaussagen, die direkt von einer Throw-Anweisung gefolgt werden.

Schlüssel : CQRules:CQBP-44---ConsecutivelyLogAndThrow
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Ein weiteres gängiges Muster, das vermieden werden sollte, ist die Protokollierung einer Nachricht, direkt gefolgt von der Auslösung einer Ausnahme. Dadurch erscheint die Ausnahmemeldung in Protokolldateien meist doppelt.

Nicht konformer Code

public void dontDoThis() throws Exception {
  logger.error("something went wrong");
  throw new RuntimeException("something went wrong");
}

Konformer Code

public void doThis() throws Exception {
  throw new RuntimeException("something went wrong");
}

Vermeiden Sie beim Verarbeiten von GET- oder HEAD-Anfragen die Protokollierung bei INFO.

Schlüssel : CQRules:CQBP-44---LogInfoInGetOrHeadRequests
Typ : Code Smell
Schweregrad : Gering
Im Allgemeinen sollten mit der Protokollierungsstufe INFO wichtige Aktionen abgegrenzt werden. Standardmäßig ist AEM so konfiguriert, dass auf der INFO-Ebene oder höher protokolliert wird. GET- und HEAD-Methoden sollten nur schreibgeschützte Vorgänge sein und stellen daher keine wichtigen Aktionen dar. Die Protokollierung auf INFO-Ebene als Antwort auf GET- oder HEAD-Anfragen füllt das Protokoll wahrscheinlich mit erheblichen Mengen überflüssiger Informationen, sodass es schwieriger wird, nützliche Informationen in Protokolldateien zu finden. Bei der Verarbeitung von GET- oder HEAD-Anfragen sollte die Protokollierung entweder bei einem Fehler auf WARN- oder ERROR-Ebene erfolgen oder auf DEBUG- oder TRACE-Ebene, wenn eine tiefgehendere Fehlerbehebung hilfreich wäre.
Das gilt nicht für die Protokollierung von access.log-type-Ereignissen für jede Anfrage.

Nicht konformer Code

public void doGet() throws Exception {
  logger.info("handling a request from the user");
}

Konformer Code

public void doGet() throws Exception {
  logger.debug("handling a request from the user.");
}

Verwenden Sie nicht Exception.getMessage() als ersten Parameter einer Protokollanweisung.

Schlüssel : CQRules:CQBP-44---ExceptionGetMessageIsFirstLogParam
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Als Best Practice sollten Protokollmeldungen kontextbezogene Informationen darüber enthalten, wo eine Anwendungsausnahme aufgetreten ist. Während der Kontext auch mit Stacktraces bestimmt werden kann, ist die Protokollmeldung meist besser lesbar und verständlicher. Wenn Sie eine Ausnahme protokollieren, ist es daher nicht empfehlenswert, die Ausnahmemeldung als Protokollmeldung zu verwenden. Die Ausnahmemeldung enthält Informationen dazu, was nicht funktioniert hat, während die Protokollmeldung dem Protokollleser mitteilt, was die Anwendung getan hat, als die Ausnahme auftrat. Die Ausnahmemeldung wird weiterhin protokolliert. Wenn Sie Ihre eigene Meldung festlegen, werden die Protokolle verständlicher.

Nicht konformer Code

public void dontDoThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.error(e.getMessage(), e);
  }
}

Konformer Code

public void doThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.error("Unable to do something", e);
  }
}

Die Protokollierung in Catch-Blöcken sollte auf WARN- oder ERROR-Ebene erfolgen.

Schlüssel : CQRules:CQBP-44---WrongLogLevelInCatchBlock
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Wie der schon Name sagt, sollten Java-Ausnahmen immer in außergewöhnlichen Fällen verwendet werden. Wenn eine Ausnahme erfasst wird, muss daher sichergestellt sein, dass Protokollmeldungen auf der entsprechenden Ebene – WARN oder ERROR – protokolliert werden, damit diese Meldungen in den Protokollen korrekt angezeigt werden.

Nicht konformer Code

public void dontDoThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.debug(e.getMessage(), e);
  }
}

Konformer Code

public void doThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.error("Unable to do something", e);
  }
}

Drucken Sie keine Stacktraces in der Konsole.

Schlüssel : CQRules:CQBP-44---ExceptionPrintStackTrace
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Wie bereits erwähnt, ist Kontext beim Verständnis von Protokollmeldungen äußerst wichtig. Durch Verwendung von Exception.printStackTrace() wird bei der Ausgabe des Standard-Fehlerstroms nur der Stacktrace ausgegeben, sodass der gesamte Kontext verloren geht. Bei einer Multi-Thread-Anwendung wie AEM kann es beim parallelen Drucken mehrerer Ausnahmen mit dieser Methode zu einer Überlappung der Stacktraces kommen, was erhebliche Verwirrung verursacht. Ausnahmen sollten daher nur über das Protokollierungs-Framework protokolliert werden.

Nicht konformer Code

public void dontDoThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    e.printStackTrace();
  }
}

Konformer Code

public void doThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.error("Unable to do something", e);
  }
}

Verzichten Sie auf Ausgaben als Standardausgabe oder Standardfehler.

Schlüssel : CQRules:CQBP-44—LogLevelConsolePrinters
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Die Anmeldung in AEM sollte immer über das Protokollierungs-Framework (SLF4J) erfolgen. Durch die direkte Ausgabe an Standardausgabe- oder Standardfehler-Ströme gehen strukturelle und kontextbezogene Informationen verloren, die vom Protokollings-Framework bereitgestellt werden. Außerdem kann diese Vorgehensweise in einigen Fällen zu Leistungseinbußen führen.

Nicht konformer Code

public void dontDoThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    System.err.println("Unable to do something");
  }
}

Konformer Code

public void doThis() {
  try {
    someMethodThrowingAnException();
  } catch (Exception e) {
    logger.error("Unable to do something", e);
  }
}

Vermeiden Sie hartcodierte /apps- und /libs-Pfade.

Schlüssel : CQRules:CQBP-71
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2018.4.0
Im Allgemeinen sollten Pfade, die mit /libs und /apps beginnen, nicht hartcodiert werden, da die Pfade, auf die sie verweisen, am häufigsten als Pfade relativ zum Sling-Suchpfad gespeichert werden (standardmäßig /libs bzw. /apps). Durch den absoluten Pfad können geringfügige Fehler entstehen, die erst später im Projektlebenszyklus deutlich werden.

Nicht konformer Code

public boolean dontDoThis(Resource resource) {
  return resource.isResourceType("/libs/foundation/components/text");
}

Konformer Code

public void doThis(Resource resource) {
  return resource.isResourceType("foundation/components/text");
}

Die Sling-Planung sollte nicht verwendet werden

Schlüssel : CQRules:AMSCORE-554
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
Die Sling-Planung darf nicht für Aufgaben verwendet werden, für die eine garantierte Ausführung erforderlich ist. Sling Scheduled-Aufträge garantieren die Ausführung und eignen sich besser für Umgebung mit und ohne Cluster.
Weitere Informationen zum Umgang mit Sling-Aufträgen in einer Clusterbildung finden Sie unter Apache Sling Eventing und Job Handling .

AEM nicht mehr unterstützte APIs sollten nicht verwendet werden

Schlüssel : AMSCORE-553
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
Die AEM-API-Oberfläche wird ständig überarbeitet, um APIs zu identifizieren, für die keine Verwendung empfohlen wird und die daher als nicht mehr unterstützt gelten.
In vielen Fällen werden diese APIs mit der standardmäßigen Anmerkung Java @nicht mehr unterstützt und als solche mit squid:CallToDeprecatedMethod .
Es gibt jedoch Fälle, in denen eine API im Kontext von AEM nicht mehr unterstützt wird, in anderen Kontexten jedoch nicht mehr unterstützt wird. Diese Regel identifiziert diese zweite Klasse.

OakPAL-Inhaltsregeln

Unten finden Sie die OakPAL-Prüfungen, die von Cloud Manager ausgeführt werden.
OakPAL ist ein Framework, das von einem AEM-Partner (und Gewinner der Auszeichnung „AEM Rockstar North America“ von 2019) entwickelt wurde und Inhaltspakete mithilfe eines eigenständigen Oak-Repositorys überprüft.

Kundenpakete sollten keine Knoten unter /libs erstellen oder ändern

Schlüssel : BannedPaths
Typ : Fehler
Schweregrad : Blocker
Seit : Version 2019.6.0
Es ist eine lange bestehende Best Practice, dass die /libs-Inhaltsstruktur im AEM-Inhalts-Repository von Kunden als schreibgeschützt betrachtet werden sollte. Das Ändern von Knoten und Eigenschaften unter /libs verursacht erhebliche Risiken für umfassende und kleinere Aktualisierungen. Änderungen an /libs sollten nur durch Adobe über offizielle Kanäle vorgenommen werden.

Pakete dürfen keine doppelten OSGi-Konfigurationen enthalten

Schlüssel : DuplicateOsgiConfigurations
Typ : Fehler
Schweregrad : Hoch
Seit : Version 2019.6.0
Ein häufig auftretendes Problem bei komplexen Projekten besteht darin, dass dieselbe OSGi-Komponente mehrmals konfiguriert ist. Dadurch ist nicht mehr eindeutig, welche Konfiguration gelten soll. Diese Regel ist „Laufzeitmodus-fokussiert“, da sie nur Probleme erkennt, bei denen dieselbe Komponente mehrmals im gleichen Laufzeitmodus (oder mit der gleichen Kombination aus Laufzeitmodi) konfiguriert ist.

Nicht konformer Code

  + projectA
    + config
      + com.day.cq.commons.impl.ExternalizerImpl
  + projectB
    + config
      + com.day.cq.commons.impl.ExternalizerImpl

Konformer Code

  + shared-config
    + config
      + com.day.cq.commons.impl.ExternalizerImpl

Konfigurationen und Installationsordner dürfen nur OSGi-Knoten enthalten

Schlüssel : ConfigAndInstallShouldOnlyContainOsgiNodes
Typ : Fehler
Schweregrad : Hoch
Seit : Version 2019.6.0
Aus Sicherheitsgründen sind Pfade, die /config/ und /install/ enthalten, nur von Administratoranwendern in AEM lesbar und sollten nur für OSGi-Konfigurationen und OSGi-Bundles verwendet werden. Das Platzieren anderer Inhaltstypen in Pfade mit diesen Segmenten führt dazu, dass sich die Anwendung abhängig davon anders verhält, ob sie von Administratoren- oder Nicht-Administratoren verwendet wird.
Ein häufig auftretendes Problem ist die Verwendung von Knoten mit der Bezeichnung config in Komponentendialogfeldern oder beim Angeben der Rich-Text-Editor-Konfiguration für die Inline-Bearbeitung. Um dies zu beheben, sollte der fehlerhafte Knoten in einen kompatiblen Namen umbenannt werden. Nutzen Sie bei der Rich-Text-Editor-Konfiguration die Eigenschaft configPath im Knoten cq:inplaceEditing , um den neuen Speicherort anzugeben.

Nicht konformer Code

+ cq:editConfig [cq:EditConfig]
  + cq:inplaceEditing [cq:InplaceEditConfig]
    + config [nt:unstructured]
      + rtePlugins [nt:unstructured]

Konformer Code

+ cq:editConfig [cq:EditConfig]
  + cq:inplaceEditing [cq:InplaceEditConfig]
    ./configPath = inplaceEditingConfig (String)
    + inplaceEditingConfig [nt:unstructured]
      + rtePlugins [nt:unstructured]

Pakete sollten nicht überlappen

Schlüssel : PackageOverlaps
Typ : Fehler
Schweregrad : Hoch
Seit : Version 2019.6.0
Ähnlich wie bei Pakete dürfen keine doppelten OSGi-Konfigurationen enthalten ist dies ein häufiges Problem bei komplexen Projekten, bei denen mehrere separate Inhaltspakete in denselben Knotenpfad schreiben. Mit Inhaltspaketabhängigkeiten kann zwar ein konsistentes Ergebnis sichergestellt werden, Überlappungen sollten aber dennoch von vorneherein vermieden werden.

Standard-Authoring-Modus sollte keine klassische Benutzeroberfläche sein

Schlüssel : ClassicUIAuthoringMode
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
Die OSGi-Konfiguration com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl definiert den Standard-Authoring-Modus in AEM. Da die klassische Benutzeroberfläche seit AEM 6.4 nicht mehr unterstützt wird, wird jetzt ein Problem angezeigt, wenn der Standard-Authoring-Modus auf die klassische Benutzeroberfläche konfiguriert ist.

Komponenten mit Dialogen sollten Touch-UI-Dialoge haben

Schlüssel : ComponentWithOnlyClassicUIDialog
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
AEM-Komponenten mit einem Dialogfeld für die klassische Benutzeroberfläche sollten immer über ein entsprechendes Dialogfeld für die Touch-Benutzeroberfläche verfügen, um eine optimale Authoring-Funktion zu bieten und mit dem Cloud-Dienstbereitstellungsmodell kompatibel zu sein, bei dem die klassische Benutzeroberfläche nicht unterstützt wird. Diese Regel überprüft die folgenden Szenarien:
  • Eine Komponente mit einem Dialogfeld für die klassische Benutzeroberfläche (d. h. ein untergeordneter Knoten im Dialogfeld) muss über ein entsprechendes Dialogfeld für die Touch-Benutzeroberfläche verfügen (d. h. über einen cq:dialog untergeordneten Knoten).
  • Eine Komponente mit einem Dialogfeld für das Design der klassischen Benutzeroberfläche (d. h. ein Knoten "design_dialog") muss über ein entsprechendes Dialogfeld für das Design der Touch-Benutzeroberfläche verfügen (d. h. einen cq:design_dialog untergeordneten Knoten).
  • Eine Komponente mit einem Dialogfeld für die klassische Benutzeroberfläche und einem Dialogfeld für die klassische Benutzeroberfläche muss sowohl über ein entsprechendes Dialogfeld für die Touch-Benutzeroberfläche als auch über ein entsprechendes Dialogfeld für das Touch-UI-Design verfügen.
Die Dokumentation zu den AEM-Moderationstools enthält Dokumentation und Werkzeuge zum Konvertieren von Komponenten aus der klassischen Benutzeroberfläche in die Touch-Benutzeroberfläche. Weitere Informationen finden Sie in den AEM-Modernisierungstools .

Pakete sollten keinen veränderlichen und nicht veränderlichen Inhalt mischen

Schlüssel : ImmutableMutableMixedPackage
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
Um mit dem Bereitstellungsmodell für den Cloud-Dienst kompatibel zu sein, müssen einzelne Inhaltspakete entweder Inhalte für die unveränderlichen Bereiche des Repositorys enthalten (d. h., sie /apps and /libs, although /libs sollten nicht durch Kundencode geändert werden und verursachen eine separate Verletzung) oder den veränderlichen Bereich (d. h. alles andere), jedoch nicht beide. Beispielsweise /apps/myco/components/text and /etc/clientlibs/myco ist ein Paket, das beide enthält, nicht mit dem Cloud-Dienst kompatibel und führt dazu, dass ein Problem gemeldet wird.
Weitere Informationen finden Sie unter AEM-Projektstruktur .

Rückwärtsreplikationsagenten sollten nicht verwendet werden

Schlüssel : ReverseReplication
Typ : Code Smell
Schweregrad : Gering
Seit : Version 2020.5.0
In Cloud-Dienstbereitstellungen ist keine Unterstützung für die umgekehrte Replizierung verfügbar, wie in den Versionshinweisen beschrieben: Entfernung von Replizierungsagenten .
Kunden, die die umgekehrte Replizierung verwenden, sollten sich für alternative Lösungen an Adobe wenden.