SlideShare a Scribd company logo
1 of 43
Download to read offline
The Java Chamber of Horrors
Andreas Zitzelsberger
@andreasz82
QAware
1≅0
if (true == lUsingHttps) {
// ...
}
if (true == lUsingHttps) {
//..
if (lUsingSSLContext) { /* ... */ }
//..
if (true == lUsingHttps) {
if (true == lUsingSSLContext) { /* ... */ }
}
// ...
}
Better double
check!
Interleave
control flows
„true".equals(request.getParameter("statsRequired"))
? true: false
Make the result
extra-boolean
If only there was a
parseBoolean
method
if (dateCache.after(dateUser) || dateCache.equals(dateUser)) {
return false;
} else {
return true;
}
if (dateCache.after(dateUser) || dateCache.equals(dateUser)) {
return true;
} else {
return false;
}
Strings!
if (clazz != null) {
header.concat(LayoutConst.CLASS_NAME_STR);
header.concat(clazz.getName());
header.concat(LayoutConst.NEW_LINE);
}
Early implementation of
github.com/kelseyhightower/noco
de
public final static String NAME = new String("PIE DIAGRAM");
String surplus = new String(" ");
new String(Long.toString(rightPoint));
new String("col" + String.valueOf(z + 2));
Me want objects!
GC
Objects.equals(
query.getHost(),
hostName)
Which of these are equal?
• Localhost
• LoCaLhOsT
• localhost.localdomain
• 127.0.0.1
• 127.0.0.2
• 192.168.178.5
• my-computer
• my-computer.my-domain
Exceptional
exception
handling
} catch (Exception ex) {
throw ex;
}
} catch (Exception e) {
// improbable exceptions, throw a runtime exception
// to avoid the declaration in the method-signature
throw new RuntimeException( "... failed", e);
}
} catch (Exception ex) {
// this exception will be ignored
// because it cannot be sensibly handled
;
} Why is there a
semicolon?
} catch (SQLException sqlException) {
; // to be compliant with rule NoEmptyCatchBlocks
}
Ah, that’s why!
try {
Thread.sleep(retryWaitTime);
} catch (InterruptedException e) {
; // nothing to do
}
Unless you want your
thread to be able to
shut down …
try {
nextLogger.setLogger(
logManager.currentLogger(nextLoggerName));
loggerTable.remove(nextLoggerName);
} catch (Throwable t) {
failed = true;
}
@SuppressFBWarnings(value=„REC_CATCH_EXCEPTION“,
justification="silly rule")
Security!
HttpServletResponseWrapper {
/* ... */
public void setHeader(String arg0, String arg1) {
// in this case do nothing here,
// because we are setting it in the filter
}
public void setContentType(String arg0) {
// in this case do nothing here,
// because we are setting it in the filter
}
Breaks contract of
HttpServletResponse
public class PasswordEncryptor {
private static final byte[] ALGO = new byte[]{68, 69, 83};
public static String encrypt(String str) throws
BadPaddingException, IllegalBlockSizeException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, UnsupportedEncodingException {
// ...
Cipher cipher = Cipher.getInstance(new String(ALGO));
cipher.init(1, new SecretKeySpec(key,
new String(ALGO)));
// ...
}
}
D E S
Misoverengineerin
g!
public class ServiceInvocationHandler implements InvocationHandler {
private final BusinessService underlyingBusinessService;
private final BusinessService derivedFromBusinessService;
public Object invoke(/* ... */ ) throws Throwable {
/* ... */
}
public static Object getService(/* ... */) {
/* ... */
}
}
Let’s call these
delegate and
caller for the sake
of clarity…
public Object invoke(final Object proxy, final Method method,
final Object[] args) throws Throwable {
try {
if (caller == null)
delegate.setSession(HibernateUtil.getSessionFactory()
.getCurrentSession());
else {
Assert.isNotNull(caller.getSession());
delegate.setSession(caller.getSession());
}
delegate.beginTransaction();
final Object ret = method.invoke(delegate, args);
// continued ...
No Caller → New
Hibernate session
Otherwise, use
the caller’s
session
Wait, what if there
already is an open
transaction?
if (caller == null)
delegate.commit();
if (delegate instanceof ServiceWithAssociatedThread
&& ((ServiceWithAssociatedThread) delegate)
.hasAssociatedThread()) {
((ServiceWithAssociatedThread) delegate)
.startAssociateThread();
((ServiceWithAssociatedThread) delegate)
.removeAssociateThread();
}
return ret;
} catch (final Throwable throwable) {
// continued …
}
Unfinished
transaction if
there is a caller
What could go
wrong?
} catch (final Throwable throwable) {
Logger.error(ServiceInvocationHandler.class,
„Error ...", throwable);
if (caller == null && delegate.hasTransaction())
delegate.rollback();
else if (caller != null && caller.hasTransaction())
caller.rollback();
throw throwable.getCause();
} finally {
if (delegate.hasSession()) {
//if (caller != null)
// delegate.close();
delegate.setSession(null);
}
Wait, what?
Wait for the GC
to clean up after
us
Modify stack trace,
possible
NullPointerException
Integration
Business
What (probably) has happened
Presentation
Service Service Service
Transaction Facade
The setting:
A massive custom framework for
web apps.
Think JEE built in-house
protected void reset() {
String[] classesForReset =
{
„com.acmecorp...legitimaton...XService",
„com.acmecorp...legitimaton...YService",
"com.acmecorp...legitimaton...ZService",
// ...
};
// continued ...
Boss music
starts…
for (int i = 0; i < classesForReset.length; i++) {
try {
Class class = class.forName(classesForReset[i]);
Method method = class.getDeclaredMethod(
„reset", new Class[0]);
method.invoke(null, null);
} catch Exception e) {
System.err.println(/* ... */);
e.printStackTrace(System.err);
}
}
Call a static reset
method on each class
for each request
How bad can it be?
public static void reset() {
ldapFilters = new HashMap();
}
Filters for per-
user LDAP
queries
public static void reset() {
sslSocketFactory = null;
}
New connections
for each request
What (probably) has happened
• Stored session state in static variables (maybe a former C programmer?)
• We need a reset() method, but it has to be static
• Can’t use an interface for static methods
• Call them by reflection
• Forget about this code and have it run in production...
• ...for over 10 years
• ...in almost 300 applications
What language do you want to
have bad code in?
Thank you!
@andreasz82
Bonus:
More bad code
private static void copyHashMap(HashMap<String,String> source, HashMap<String,String> destination) {
if ((source != null) && (destination != null)) {
if (!destination.isEmpty()) {
destination.clear();
}
for(HashMap.Entry<String, String> entry: source.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
destination.put(new String(key), new String(value));
}
}
}
return super.isIdentical(msg) && germanMsg != null ?
germanMsg.getMsg().equals(msg.getMsg(Locale.GERMAN)):
true && defaultMsg != null ?
defaultMsg.getMsg().equals(msg.getMsg(DEFAULT_LOCALE)):
true;
public AcmeCorpInteger(int intValue) {
this();
try {
setValue(new BigInteger("" + intValue));
} catch (AcmeCorpDatatypeConditionError ex) {
}
}
Integer enterpriseNo = new Integer(
enterpriseDTO.getEnterpriseNo().getValue().intValue());
setCookie(
(new Long(userSession.getAccessTime())).toString(),
response);
public URLConnection(String[] urls, int maxRetries, long waitMs) {
super(getUrlFromString(urls[0]));
if ((null == urls) || (urls.length <= 0)) {
throw new RuntimeException("empty urls");
}
// ...
}
//NOBUG
//Only to satisfy constructor

More Related Content

More from QAware GmbH

Cloud Migration mit KI: der Turbo
Cloud Migration mit KI: der Turbo Cloud Migration mit KI: der Turbo
Cloud Migration mit KI: der Turbo QAware GmbH
 
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
 Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See... Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...QAware GmbH
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster QAware GmbH
 
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.QAware GmbH
 
Kubernetes with Cilium in AWS - Experience Report!
Kubernetes with Cilium in AWS - Experience Report!Kubernetes with Cilium in AWS - Experience Report!
Kubernetes with Cilium in AWS - Experience Report!QAware GmbH
 
50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling50 Shades of K8s Autoscaling
50 Shades of K8s AutoscalingQAware GmbH
 
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAPKontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAPQAware GmbH
 
Service Mesh Pain & Gain. Experiences from a client project.
Service Mesh Pain & Gain. Experiences from a client project.Service Mesh Pain & Gain. Experiences from a client project.
Service Mesh Pain & Gain. Experiences from a client project.QAware GmbH
 
50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling50 Shades of K8s Autoscaling
50 Shades of K8s AutoscalingQAware GmbH
 
Blue turns green! Approaches and technologies for sustainable K8s clusters.
Blue turns green! Approaches and technologies for sustainable K8s clusters.Blue turns green! Approaches and technologies for sustainable K8s clusters.
Blue turns green! Approaches and technologies for sustainable K8s clusters.QAware GmbH
 
Per Anhalter zu Cloud Nativen API Gateways
Per Anhalter zu Cloud Nativen API GatewaysPer Anhalter zu Cloud Nativen API Gateways
Per Anhalter zu Cloud Nativen API GatewaysQAware GmbH
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster QAware GmbH
 
How to speed up Spring Integration Tests
How to speed up Spring Integration TestsHow to speed up Spring Integration Tests
How to speed up Spring Integration TestsQAware GmbH
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-ClusterAus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-ClusterQAware GmbH
 
Cloud Migration – Eine Strategie die funktioniert
Cloud Migration – Eine Strategie die funktioniertCloud Migration – Eine Strategie die funktioniert
Cloud Migration – Eine Strategie die funktioniertQAware GmbH
 
Policy Driven Microservices mit Open Policy Agent
Policy Driven Microservices mit Open Policy AgentPolicy Driven Microservices mit Open Policy Agent
Policy Driven Microservices mit Open Policy AgentQAware GmbH
 
Make Developers Fly: Principles for Platform Engineering
Make Developers Fly: Principles for Platform EngineeringMake Developers Fly: Principles for Platform Engineering
Make Developers Fly: Principles for Platform EngineeringQAware GmbH
 
Security Lab: OIDC in der Praxis
Security Lab: OIDC in der PraxisSecurity Lab: OIDC in der Praxis
Security Lab: OIDC in der PraxisQAware GmbH
 
Die nächsten 100 Microservices
Die nächsten 100 MicroservicesDie nächsten 100 Microservices
Die nächsten 100 MicroservicesQAware GmbH
 
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?Enterprise-level Kubernetes Security mit Open Source Tools - geht das?
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?QAware GmbH
 

More from QAware GmbH (20)

Cloud Migration mit KI: der Turbo
Cloud Migration mit KI: der Turbo Cloud Migration mit KI: der Turbo
Cloud Migration mit KI: der Turbo
 
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
 Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See... Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
 
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
 
Kubernetes with Cilium in AWS - Experience Report!
Kubernetes with Cilium in AWS - Experience Report!Kubernetes with Cilium in AWS - Experience Report!
Kubernetes with Cilium in AWS - Experience Report!
 
50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling
 
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAPKontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
 
Service Mesh Pain & Gain. Experiences from a client project.
Service Mesh Pain & Gain. Experiences from a client project.Service Mesh Pain & Gain. Experiences from a client project.
Service Mesh Pain & Gain. Experiences from a client project.
 
50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling50 Shades of K8s Autoscaling
50 Shades of K8s Autoscaling
 
Blue turns green! Approaches and technologies for sustainable K8s clusters.
Blue turns green! Approaches and technologies for sustainable K8s clusters.Blue turns green! Approaches and technologies for sustainable K8s clusters.
Blue turns green! Approaches and technologies for sustainable K8s clusters.
 
Per Anhalter zu Cloud Nativen API Gateways
Per Anhalter zu Cloud Nativen API GatewaysPer Anhalter zu Cloud Nativen API Gateways
Per Anhalter zu Cloud Nativen API Gateways
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
 
How to speed up Spring Integration Tests
How to speed up Spring Integration TestsHow to speed up Spring Integration Tests
How to speed up Spring Integration Tests
 
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-ClusterAus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
 
Cloud Migration – Eine Strategie die funktioniert
Cloud Migration – Eine Strategie die funktioniertCloud Migration – Eine Strategie die funktioniert
Cloud Migration – Eine Strategie die funktioniert
 
Policy Driven Microservices mit Open Policy Agent
Policy Driven Microservices mit Open Policy AgentPolicy Driven Microservices mit Open Policy Agent
Policy Driven Microservices mit Open Policy Agent
 
Make Developers Fly: Principles for Platform Engineering
Make Developers Fly: Principles for Platform EngineeringMake Developers Fly: Principles for Platform Engineering
Make Developers Fly: Principles for Platform Engineering
 
Security Lab: OIDC in der Praxis
Security Lab: OIDC in der PraxisSecurity Lab: OIDC in der Praxis
Security Lab: OIDC in der Praxis
 
Die nächsten 100 Microservices
Die nächsten 100 MicroservicesDie nächsten 100 Microservices
Die nächsten 100 Microservices
 
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?Enterprise-level Kubernetes Security mit Open Source Tools - geht das?
Enterprise-level Kubernetes Security mit Open Source Tools - geht das?
 

Recently uploaded

Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmuxevmux96
 
Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14VMware Tanzu
 
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxFrom Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxNeo4j
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AIAGATSoftware
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jNeo4j
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksJinanKordab
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Flutter Agency
 
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckMarc Lester
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Maxim Salnikov
 
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-CloudAlluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-CloudAlluxio, Inc.
 
Test Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfTest Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfkalichargn70th171
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAShane Coughlan
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletAndrea Goulet
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdfSelfMade bd
 
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphGraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphNeo4j
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypseTomasz Kowalczewski
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNeo4j
 
Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMarkus Moeller
 

Recently uploaded (20)

Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmux
 
Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14
 
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxFrom Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with Links
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
 
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined Deck
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
 
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
 
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-CloudAlluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
 
Test Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfTest Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdf
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
 
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphGraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMs
 
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
 
Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdf
 

The Java Chamber of Horrors

  • 1. The Java Chamber of Horrors Andreas Zitzelsberger @andreasz82 QAware
  • 3. if (true == lUsingHttps) { // ... }
  • 4. if (true == lUsingHttps) { //.. if (lUsingSSLContext) { /* ... */ } //.. if (true == lUsingHttps) { if (true == lUsingSSLContext) { /* ... */ } } // ... } Better double check! Interleave control flows
  • 5. „true".equals(request.getParameter("statsRequired")) ? true: false Make the result extra-boolean If only there was a parseBoolean method
  • 6. if (dateCache.after(dateUser) || dateCache.equals(dateUser)) { return false; } else { return true; }
  • 7. if (dateCache.after(dateUser) || dateCache.equals(dateUser)) { return true; } else { return false; }
  • 9. if (clazz != null) { header.concat(LayoutConst.CLASS_NAME_STR); header.concat(clazz.getName()); header.concat(LayoutConst.NEW_LINE); } Early implementation of github.com/kelseyhightower/noco de
  • 10. public final static String NAME = new String("PIE DIAGRAM"); String surplus = new String(" "); new String(Long.toString(rightPoint)); new String("col" + String.valueOf(z + 2)); Me want objects! GC
  • 11. Objects.equals( query.getHost(), hostName) Which of these are equal? • Localhost • LoCaLhOsT • localhost.localdomain • 127.0.0.1 • 127.0.0.2 • 192.168.178.5 • my-computer • my-computer.my-domain
  • 13. } catch (Exception ex) { throw ex; }
  • 14. } catch (Exception e) { // improbable exceptions, throw a runtime exception // to avoid the declaration in the method-signature throw new RuntimeException( "... failed", e); }
  • 15. } catch (Exception ex) { // this exception will be ignored // because it cannot be sensibly handled ; } Why is there a semicolon?
  • 16. } catch (SQLException sqlException) { ; // to be compliant with rule NoEmptyCatchBlocks } Ah, that’s why!
  • 17. try { Thread.sleep(retryWaitTime); } catch (InterruptedException e) { ; // nothing to do } Unless you want your thread to be able to shut down …
  • 21. HttpServletResponseWrapper { /* ... */ public void setHeader(String arg0, String arg1) { // in this case do nothing here, // because we are setting it in the filter } public void setContentType(String arg0) { // in this case do nothing here, // because we are setting it in the filter } Breaks contract of HttpServletResponse
  • 22. public class PasswordEncryptor { private static final byte[] ALGO = new byte[]{68, 69, 83}; public static String encrypt(String str) throws BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException { // ... Cipher cipher = Cipher.getInstance(new String(ALGO)); cipher.init(1, new SecretKeySpec(key, new String(ALGO))); // ... } } D E S
  • 24. public class ServiceInvocationHandler implements InvocationHandler { private final BusinessService underlyingBusinessService; private final BusinessService derivedFromBusinessService; public Object invoke(/* ... */ ) throws Throwable { /* ... */ } public static Object getService(/* ... */) { /* ... */ } } Let’s call these delegate and caller for the sake of clarity…
  • 25. public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { try { if (caller == null) delegate.setSession(HibernateUtil.getSessionFactory() .getCurrentSession()); else { Assert.isNotNull(caller.getSession()); delegate.setSession(caller.getSession()); } delegate.beginTransaction(); final Object ret = method.invoke(delegate, args); // continued ... No Caller → New Hibernate session Otherwise, use the caller’s session Wait, what if there already is an open transaction?
  • 26. if (caller == null) delegate.commit(); if (delegate instanceof ServiceWithAssociatedThread && ((ServiceWithAssociatedThread) delegate) .hasAssociatedThread()) { ((ServiceWithAssociatedThread) delegate) .startAssociateThread(); ((ServiceWithAssociatedThread) delegate) .removeAssociateThread(); } return ret; } catch (final Throwable throwable) { // continued … } Unfinished transaction if there is a caller What could go wrong?
  • 27. } catch (final Throwable throwable) { Logger.error(ServiceInvocationHandler.class, „Error ...", throwable); if (caller == null && delegate.hasTransaction()) delegate.rollback(); else if (caller != null && caller.hasTransaction()) caller.rollback(); throw throwable.getCause(); } finally { if (delegate.hasSession()) { //if (caller != null) // delegate.close(); delegate.setSession(null); } Wait, what? Wait for the GC to clean up after us Modify stack trace, possible NullPointerException
  • 28. Integration Business What (probably) has happened Presentation Service Service Service Transaction Facade
  • 29. The setting: A massive custom framework for web apps. Think JEE built in-house
  • 30. protected void reset() { String[] classesForReset = { „com.acmecorp...legitimaton...XService", „com.acmecorp...legitimaton...YService", "com.acmecorp...legitimaton...ZService", // ... }; // continued ... Boss music starts…
  • 31. for (int i = 0; i < classesForReset.length; i++) { try { Class class = class.forName(classesForReset[i]); Method method = class.getDeclaredMethod( „reset", new Class[0]); method.invoke(null, null); } catch Exception e) { System.err.println(/* ... */); e.printStackTrace(System.err); } } Call a static reset method on each class for each request
  • 32. How bad can it be? public static void reset() { ldapFilters = new HashMap(); } Filters for per- user LDAP queries public static void reset() { sslSocketFactory = null; } New connections for each request
  • 33.
  • 34. What (probably) has happened • Stored session state in static variables (maybe a former C programmer?) • We need a reset() method, but it has to be static • Can’t use an interface for static methods • Call them by reflection • Forget about this code and have it run in production... • ...for over 10 years • ...in almost 300 applications
  • 35. What language do you want to have bad code in?
  • 38. private static void copyHashMap(HashMap<String,String> source, HashMap<String,String> destination) { if ((source != null) && (destination != null)) { if (!destination.isEmpty()) { destination.clear(); } for(HashMap.Entry<String, String> entry: source.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); destination.put(new String(key), new String(value)); } } }
  • 39. return super.isIdentical(msg) && germanMsg != null ? germanMsg.getMsg().equals(msg.getMsg(Locale.GERMAN)): true && defaultMsg != null ? defaultMsg.getMsg().equals(msg.getMsg(DEFAULT_LOCALE)): true;
  • 40. public AcmeCorpInteger(int intValue) { this(); try { setValue(new BigInteger("" + intValue)); } catch (AcmeCorpDatatypeConditionError ex) { } }
  • 41. Integer enterpriseNo = new Integer( enterpriseDTO.getEnterpriseNo().getValue().intValue());
  • 43. public URLConnection(String[] urls, int maxRetries, long waitMs) { super(getUrlFromString(urls[0])); if ((null == urls) || (urls.length <= 0)) { throw new RuntimeException("empty urls"); } // ... } //NOBUG //Only to satisfy constructor