Create sources jar for shrunk classes in a module via proguard - java

There is a business module - say kilo-business in one of the applications. Now there are some APIs in this module that is to be used by another application (locally within the organization - say kilo-client1). I have used Proguard (via its maven plugin) to only extract the classes relevant to the API and make a JAR out of it - the shrunk API JAR called kilo-business-apis. kilo-client1 uses this kilo-business-apis dependency and invokes the service. As a policy, we always include sources along with any artifact that we share between applications (for debugging ease and additional documentation).
In this case, is there a way that one can have Proguard also give out the (probable) source files (belonging to kilo-business module) from where it has sourced the classes for the kilo-business-apis using which a sources JAR can be conjured? Actually, we don't shrink the JAR to the extent of removing unused methods/variables from the class, so giving out the source java files would also suffice.
I understand that one can use jd-eclipse or some other decompiler in eclipse to aid debugging even if we don't publish it, but wanted to check if we can generate the sources first class whereby documentation needs are also addressed.
One thought is to break up kilo-business itself into a separate module for kilo-business-apis where only the API definitions reside and both kilo-business and kilo-client1 can use it, but unfortunately I can't do it for legacy reasons.
Thanks in advance!

ProGuard optionally writes out information about kept entry points (-printseeds), unused code (-printusage), and obfuscation mapping (-printmapping), but nothing related to source files. If you don't obfuscate the code, you can simply list the .class names in the processed output, and find the corresponding .java files.

Related

File sources of classes present in two libraries in IntelliJ

I'm using Gradle on IntelliJ and I have a peculiar issue with my dependencies: two of them contain a few of the same classes (apart from other files from each library), but one comes with the sources and the other one doesn't. The result is IntelliJ gives preference over to the one that doesn't contain the sources and I have to attach them manually (which is bad, because they'll be gone on every Gradle sync).
How can I choose the order of preference? And yes, I need both dependencies, even with their issues, but I also need the sources of the common files.

AEM 6.1 Sightly Java class does not update on build

I have recently started using Sightly in AEM 6.1, which allows the Java files to be located in the same folder as the component and use the WCMUse class. However, I am noticing that whenever I do a Maven build that involves a change to one of those Java files that the page functionality operates as if the Java class had not been changed, though the Java file in the crx does include the changes. As a workaround I have been been able to modify the Java file in the crx, save it, then modify it back and save again in order to update the functionality, but I do not have that capability on all of my instances.
Anybody have an idea how to force the recompile of the Sightly Java within the components either during or following the build?
A few things to validate:
1- Do you change the version of the software when doing a maven build/deploy? Sometime if your zip or jar does not have -SNAPSHOT in it AEM won't update the code when maven deploys.
2- there a /var/classes/sightly in CRX/DE that you can delete compiled classes, I think even in the system console there is an entry
Hope this help.
Bambara actually helped me get to the answer that I needed. It turns out the /var/classes folder holds the compiled sightly files, but it doesn't naturally recompile on build. Deleting that folder on build, then running a page that uses the sightly code forces a recompile and shows the new functionality.
Hopefully others can answer why this happens and how to avoid it. Having faced this a number of times, I'm beginning to think placing Java code into the component folders is not a very good idea. Using a maven multi-module project with a Services/Core bundle, then all Java code could go there. Calling it from the view just requires using the fully qualified classname (including the package). Placing the Java into the services bundle has the following benefits
Allows the classes to be extended. For some reason compilation was unpredictable when extending classes from component folders.
Easier IDE setup. Java classes in component folders in the view module have a Sling specific folder structure, so getting IDE's to provide code assist requires extra effort.
Sling folder conventions follow URI practices and might have dashes, Java packages cannot have dashes... import apps.my-cool-project.components.pages.base.Header; // won't compile

Missing jar file error

I am developing an application with many functionality, where one functionality requires a jar file which is only commercially available. When I release it for public use for free, I have to remove this jar file from my source. When I run this application in Eclipse IDE with the jar file removed, it gives me "Errors exist in required Project". I would like to avoid this warning.
Only the users using the library should be able to access its corresponding functionality (The application has many functionality.)
Users who don't include this jar file should be able to access other functionality without any error/warning.
Requirement:
Gray out the functionality based on the absence of the jar file.
Avoid the warning message when I run the Main.java
Any help appreciated. Thanks!
What you need indeed is dynamic class loading, isn't it?
To enable this feature, you have some options:
Implement your own classloader.
Use OSGI.
Additional to yanana's solution, you can simply leave the commercial JAR file in your Eclipse project. When creating your setup you can create one setup for commercial use (including the JAR) and one for the open source version (without the JAR).
But you should be carefully separate the usage of the commercial classes into one or more package/module. At runtime you can check the presence of one class which is part of the commerical JAR file via reflection before accessing code dependent on the commercial JAR.
Your integration tests should contain some corresponding test cases with and without the commercial JAR in classpath.

Minimizing external JAR by removing all non-dependent classes from source code

I have an Android project which requires Apache's POI external JARs (libraries used to read and manipulate MS Office files, but that's irrelevant).
Upon compilation I get an error stating that my project has over 65536 method declarations - I only have a few dozens and the rest are from the external libraries.
I only need a fraction of the functionality of POI so I downloaded the full source code and imported it into Eclipse. I have a list of classes I'd like to keep, however each one of these classes depends on other classes in the code, and I can only assume that these classes also have dependencies.
Is there a way to clean the source code so I'd keep only the classes I need and all their dependencies (without manually tracking each dependency, as there are a lot of them)?
P.S - I've looked at this question but it deals with compiled JARs and I also have the source code.

Location of generated source files for maven directory structure

Besides src/main/java folder, we have one folder that contains some generated java sources that are required for the main sources. Code generation is invoked manually, when needed. Generated source is checked into the source repo. Everything will be built and packed together.
What would be the best location for generated java sources that are going to be compiled together with main sources? Should it be:
/src/generated/java (following the same naming logic for src/testInt/java for integration tests)
/generated-src/main/java (in collision with "The src directory contains all of the source material for building the project")
/src/main/generated-java (well... generated-java is not a type)
...?
The first option seems like the most appropriate one for this case. What do you think? Is there anything in Maven docs that describes this situation (that I have overlooked)? Do you know any repo with similar structure?
Thank you.
Answer
As suggested by #Absurd-Mind, direction we are thinking about is to split the source into the submodules (which works nice in gradle). So, the generated source and some other related source will go into its own submodule (they will produce the separate artifact) and the rest will go in other submodule, that uses this one. Thank you.
I think the location depends on how the source is generated and handled.
The source code is generated automatically during the build process: Then i would use target/main/java/, target/test/java/ and so on. This code is not checked in into CVS since you can rebuild it fairly easy. In case you clean your project the target directory will be removed and the source will be rebuild.
The source code is generated manually by an external tool or similar: I would use generated/src/main/java/, generated/src/test/java/, generated/src/main/resources/ and so on. This code should be checked in. A benefit is, as soon you see that the top-level directory name is generated you know that all files/directories below are also generated. Also you have the standard maven directory structure under the top-level directory. Another point is that clean-up is easy, just delete generated and recreate it, without looking through many other directories (like in your example: src/main/generated-java and src/test/generated-java).
EDIT: Another nice solution would be to create a maven project which only contains the generated source like myproject-generated-1.0.3.jar. This project would be a dependency in your real application. Then you would just put your generated source int src/main/java.
As much as i know there is no standard folder structure for generated sources. In my projects, i prefer src/gen/java kind of notation.
I totally agree with the accepted answer. I just want to offer a slightly different suggestion for naming the directory that contains code generated by third-party tools:
src-gen/main/java
Background: In the Eclipse/Maven Tycho world (where code/resource generation often plays a large role) there is the src-gen directory for generated code, which has been established as some kind of standard convention. (the default project layout is a bit different compared to Maven, as all source files are directly in src and src-gen).
In a Maven project that could be translated for example to src-gen/main/java, src-gen/main/resources, src-gen/test/java, src-gen/test/resources. I like that more than moving everything into a "generated" directory, because
Sources in src/main/javaand src-gen/main/java are on the same depth in the directory tree
It's more clear that src-gen contains generated sources/resources that contribute to the build. On the other hand a folder just named "generated" dosn't tell you much about its content. It could contain anything, like generated documentation or generated test data or it could be just a temporary folder.
All the mentioned advantages of generated/src/main/java still apply (e.g. easy cleanup)
After a quick google search it looks like there are already projects on Github that use this pattern
Some thoughts/opinions about the other suggestions from the question:
Instead of /src/main/generated-java I would probably rather go with something like /src/main/java-gen which, when sorting directories alphabetically, keeps generated and regular code next to each other (<lang>-gen is also another pattern already used in Eclipse projects)
In my opinion gen fits in with the brief official names like src, it etc. more than generated. I've already seen src/gen/java a few times in the wild and have the feeling it is a more common than /src/generated/java. On the other hand some Maven plugins use the quite verbose target/generated-sources/<lang> directory, so generated-sources/main/java could also be an option if your not into short names...
Ultimately I think the naming doesn't matter that much and it is up to your preference since none of this is "official" convention.
NetBeans adopted <project>/target/generated-sources/<tool> as the location for generated code. As a result you would see an extra leaf appear in your project tree named as Generated Sources (<tool>), and source code will be navigable and not show up with compiler errors in the markup.
So if you commit your code, it will not be under the /target directory, and you will have to setup your maven project for the additional Source Code locations. Otherwise, I will suggest to keep with that adopted standard and put things under <project>/target/generated-sources/<tool>.
In Maven project source file store inside src/main/java , src/main/resources and test class store inside src/test/java.
In Maven generated code (Compile code) stored into target/ folder.
When you build your Maven project, all generated code to be updated in target folder.

Categories

Resources