<?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: L. Berger</title>
    <description>The latest articles on DEV Community by L. Berger (@fohlen).</description>
    <link>https://dev.to/fohlen</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%2F87714%2F727714e0-cf28-4272-9e35-bf877cff448b.jpg</url>
      <title>DEV Community: L. Berger</title>
      <link>https://dev.to/fohlen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fohlen"/>
    <language>en</language>
    <item>
      <title>yGuard is now open source - obfuscation easy as pie</title>
      <dc:creator>L. Berger</dc:creator>
      <pubDate>Wed, 08 Jan 2020 14:53:21 +0000</pubDate>
      <link>https://dev.to/fohlen/yguard-is-now-open-source-obfuscation-easy-as-pie-1do5</link>
      <guid>https://dev.to/fohlen/yguard-is-now-open-source-obfuscation-easy-as-pie-1do5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer: This is not a sponsored post. However so my current employee pays me for maintaining the repository, so it's fair to mention them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I work for a company called &lt;a href="//yworks.com"&gt;yWorks&lt;/a&gt;. They make &lt;a href="https://www.yworks.com/products/yfiles"&gt;libraries for graphs&lt;/a&gt; that are (imho) state of the art, and also are a fun company to work at 🍺&lt;/p&gt;

&lt;p&gt;Because these libraries are sophisticated the company is very inclined to protect their intellectual property. In the golden age of Java (which was right about the time they put this onto the market) it would have been crucial to implement some sorts of protection in order to ensure this IP. This is why &lt;code&gt;yGuard&lt;/code&gt; was initially developed (side note: when I first touched the repository, some assets were as old as 11 years).&lt;/p&gt;

&lt;p&gt;I love open source - period. Knowing this, my CTO approached me a while ago, certain I would be all 🔥 for making this product available for a wider audience. We had a brief discussion and off I went on my journey to make it open-source.&lt;/p&gt;

&lt;p&gt;I made a checklist of things that needed to be addressed before releasing it to the public on GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;relicense everything that can be relicensed ✅&lt;/li&gt;
&lt;li&gt;replace proprietary code with libraries or rewrite it if necessary ✅&lt;/li&gt;
&lt;li&gt;replace ancient build system and dependencies with up-to-date ones ✅&lt;/li&gt;
&lt;li&gt;set up tests and CI so it stays in good shape ✅&lt;/li&gt;
&lt;li&gt;add extensive documentation and sample code ✅&lt;/li&gt;
&lt;li&gt;add contribution guidelines ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this list done, I'm thrilled to announce: we released &lt;a href="https://github.com/yWorks/yGuard/"&gt;yGuard&lt;/a&gt; into the wild (a while ago)!&lt;/p&gt;

&lt;p&gt;This post however should not only be a mere release announcement, but I am going to put some sample code here, so it becomes clear what this obfuscation actually does 💡&lt;/p&gt;

&lt;p&gt;Say, we have a rather complete Java application that has an entrypoint like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight mosel"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yworks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;HelloWorld&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;String&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, given we use &lt;code&gt;Gradle&lt;/code&gt; as our build system, we could use a very simple &lt;code&gt;yguard&lt;/code&gt; task to obfuscate the resulting &lt;code&gt;.jar&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;obfuscate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;dependsOn&lt;/span&gt; &lt;span class="n"&gt;jar&lt;/span&gt;

  &lt;span class="n"&gt;doLast&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;taskdef&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'yguard'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;classname:&lt;/span&gt; &lt;span class="s1"&gt;'com.yworks.yguard.YGuardTask'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;classpath:&lt;/span&gt; &lt;span class="k"&gt;sourceSets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;runtimeClasspath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asPath&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;archivePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;archiveFile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;asFile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;
    &lt;span class="n"&gt;ant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;yguard&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;inoutpair&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;in:&lt;/span&gt; &lt;span class="n"&gt;archivePath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;out:&lt;/span&gt; &lt;span class="n"&gt;archivePath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".jar"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"_obf.jar"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;shrink&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;logfile:&lt;/span&gt; &lt;span class="s2"&gt;"${buildDir}/yshrink.log.xml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;keep&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"void main(java.lang.String[])"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"class"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mainClassName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;rename&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;mainclass:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mainClassName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;logfile:&lt;/span&gt; &lt;span class="s2"&gt;"${buildDir}/yguard.log.xml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"error-checking"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="s2"&gt;"pedantic"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This tells the build system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;configure an &lt;code&gt;Ant&lt;/code&gt; task so we can use &lt;code&gt;yguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;execute the &lt;code&gt;yguard&lt;/code&gt; task with an input and output &lt;code&gt;.jar&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;shrink the resulting &lt;code&gt;.jar&lt;/code&gt;, leaving only classes and methods that are loaded from &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;obfuscate &lt;strong&gt;all&lt;/strong&gt; class names, function names, variable names, ... &lt;strong&gt;except&lt;/strong&gt; for &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we call &lt;code&gt;gradle obfuscate&lt;/code&gt; this will produce an obfuscated &lt;code&gt;.jar&lt;/code&gt;, leaving nothing but a weird trail of characters in the file names and classes.&lt;/p&gt;

&lt;p&gt;Did you notice the &lt;code&gt;logfile&lt;/code&gt; property? This is the best part. We can use the mapping established during obfuscation to unscramble stacktraces!&lt;/p&gt;

&lt;p&gt;I could write a rather lengthy article about all the possible configurations that you can use, which would far exceed a simple introduction. Maybe someday, somewhen I'll give a nice talk about how it all works 😎. In the meantime, please have a look at the &lt;a href="https://yworks.github.io/yGuard/"&gt;extensive documentation&lt;/a&gt; and &lt;a href="https://github.com/yWorks/yGuard/tree/master/examples"&gt;examples&lt;/a&gt;, which covers all of these options.&lt;/p&gt;

</description>
      <category>java</category>
      <category>obfuscation</category>
      <category>bytecode</category>
    </item>
    <item>
      <title>Why "babeling"-up harms the open source community</title>
      <dc:creator>L. Berger</dc:creator>
      <pubDate>Wed, 08 Aug 2018 14:43:21 +0000</pubDate>
      <link>https://dev.to/fohlen/why-babeling-up-harms-the-open-source-community-2fi5</link>
      <guid>https://dev.to/fohlen/why-babeling-up-harms-the-open-source-community-2fi5</guid>
      <description>

&lt;h3&gt;
  
  
  Preamble
&lt;/h3&gt;

&lt;p&gt;This article is meant as a discussion in particular about the technical attitude towards progressiveness. It is in neither way meant to insult or diminish the great work of the folks behind babel or similar tools that are mentioned. Please keep it up, you rock and the open source world definitely needs you!&lt;/p&gt;

&lt;h2&gt;
  
  
  "Babeling-up" and why it harms us
&lt;/h2&gt;

&lt;p&gt;So you've built that brand new website, or service, or piece of code. Now it's time to go awesome and ship it to the world! Okay, let's make a checklist&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] make sure all bugs are fixed before release&lt;/li&gt;
&lt;li&gt;[x] make sure you have an awesome release name&lt;/li&gt;
&lt;li&gt;[ ] make sure it runs everywhere&lt;/li&gt;
&lt;li&gt;[x] package it, upload it. There you go. The world loves you ❤️ &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now. The third part on our list is particularly cumbersome. From my experience working with the folks behind &lt;a href="https://inexor.org"&gt;Inexor&lt;/a&gt; I know that this can be almost &lt;em&gt;all&lt;/em&gt; the work. You think you're done with shipping an amazing release, but the pages turned against you and it's &lt;strong&gt;double&lt;/strong&gt; the amount of time now to get it work everywhere. So this happened to me once, twice, a third time, over and over. Full stop. One time it took me and my coworkers an entire week to make our latest feature available on IE10. I was wondering why it'd had to be this way, and it kind of makes sense for the commercial sectors. However, there is a worrying trend in the open source community, that tries to workaround this issue. Some projects that spring off my mind are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;CoffeeScript&lt;/li&gt;
&lt;li&gt;Babel&lt;/li&gt;
&lt;li&gt;Webpack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These all try to solve a common problem: bring an new featureset to older platforms.&lt;br&gt;
We are trying to comfort our users with polyfills, and at the end of the day we've spent an insane amount of time supporting all of the deprecated environments out there. I'd say this has to stop.&lt;br&gt;
The question that came up next in my mind was: &lt;em&gt;"how do we make our technologies more progressive"&lt;/em&gt;. I remember when I once helped a colleague of mine submit a feature proposal to the python committee, and as far as I can tell, it was an awfully hard experience. Reading through the W3C standards group, and the ECMA standards proposals is neither satisfying.&lt;br&gt;
It should be significantly easier to write and test enhancements. This is particularly true for browser standards, where a new idea can take years to centuries to be implemented. Therefore I suggest to those projects (yes, I am looking at you libcef, although you do much better recently) to provide mechanisms to write and ship language and framework enhancements conveniently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why pushing the implementation burden isn't enough
&lt;/h2&gt;

&lt;p&gt;Given we had those amazing API's and workflows to write enhancements, that wouldn't really change a thing. It's a good first step towards progressing technology. In the aftermath though it doesn't really change a thing. When we take a closer look at the history of software industry, there has been a huge efforts to improve this situation. Why hasn't it succeeded yet? The answer is pretty much: mindset. Most developers fear the urge of unpleasing their users with updates. This might be unfeasible for a business. For open-source, this attitude actively hinders development. We, as a community should be forcing users to keep at pace. Why support IE10? Why support Windows XP? Honestly, nobody should use that, and we should protect the software community as a whole from using deprecated environments. This is an encouragement article! Don't fear your users. Break their workflow. Progress open source. Only with a mindset where we force users to use up-to-date environments, change will finally come.&lt;br&gt;
&lt;em&gt;So please&lt;/em&gt;: next time you start a new project, don't use babel, don't use python2, don't use node4. If your user can't switch their environment, it's certainly not your responsibility to deal with. Remember: &lt;strong&gt;You&lt;/strong&gt; give your free time and effort to that project. If your user can't update because he or she is in a protected environment, hack, they should demand their administrators to make it possible!. Only such an attitude will put enough pressure on the end users, hence make progress possible.&lt;/p&gt;


</description>
      <category>opensource</category>
    </item>
  </channel>
</rss>
