Proguard keep by source file path - proguard

Proguard has options for -keep-ing a class based on its package name/hierarchy.
Is it possible to -keep based on the source file's actual path?
Example:
java/com/a/b/c/Class.java contains package com.a.b.c.Class
tests/com/a/b/c/ClassTest.java contains package com.a.b.c.ClassTest
There may be a large number of "*Test" classes and I want to Proguard -keep everything under tests/* for testing purposes. It should not keep any classes which happen to match "*Test" outside of the tests/* directory.
It doesn't seem like this would be possible with package matching since it has the same package as those classes under java/*

No, this is not possible. ProGuard does not consider the file path when applying rules.
You could use annotations for your test classes, e.g.
#TestClass
public class MyTest {
...
}
and then add a configuration like this:
-keep #TestClass class * { *; }

Related

Javalin Migration from 3 to 4

We are migrating the Javalin from 3 to 4 in our current kotlin project. the dynamicGzip has been deprecated and replaced with compression strategy.
The pom.xml part will look like below.
<properties>
<javalin.version>4.1.1</javalin.version>
<jackson.version>2.13.0</jackson.version>
</properties>
The code part of kotlin is as follows
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.*
import io.javalin.http.BadRequestResponse
import io.javalin.http.NotFoundResponse
import io.javalin.http.staticfiles.Location
import io.javalin.plugin.json.JavalinJackson
import io.javalin.core.compression.*
val app = Javalin.create { config ->
config.defaultContentType = "application/json"
config.enableWebjars()
config.addStaticFiles("", Location.CLASSPATH)
config.enableCorsForAllgOrigins()
//it.dynamicGzip = true // deprecated method which was used in 3.12.0
config.compressionStrategy(Gzip(6))
}
We are using the migrating document from this link
https://javalin.io/migration-guide-javalin-3-to-4
When we try to build the project in intelij Idea with this change, ended with the below error.
D:\app\src\main\kotlin\app\app.kt:78:40
Kotlin: Unresolved reference: Gzip
What is that we are missing here?
Also it will be helpfull if config.addStaticFiles syntax is also added wrt javalin 4
Compression
The compressionStrategy method of the JavalinConfig class takes two parameters:
void compressionStrategy(Brotli brotli, Gzip gzip)
See the JavaDoc here.
The related classes are found in Javalin here:
import io.javalin.core.compression.Brotli;
import io.javalin.core.compression.Gzip;
So, you can do something like this in your set-up (my example is Java not Kotlin):
// my Java example:
config.compressionStrategy(new Brotli(6), new Gzip(6));
Static Files
You can use something like this (again, a Java example not Kotlin):
// my Java example:
config.addStaticFiles("/public", Location.CLASSPATH);
In this case, because I want my files to be on the runtime classpath, I have also created a public directory in my application's resources directory. Your specific implementation may differ.
You can also use Location.EXTERNAL if you prefer, to place the files somewhere else in your filesystem (outside the application).
Note also there is a small typo in config.enableCorsForAllgOrigins(). It should be:
config.enableCorsForAllOrigins()

Avro generated class: Cannot access class 'Builder'. Check your module classpath for missing or conflicting dependencies

Running
val myAvroObject = MyAvroObject.newBuilder()
results in a compilation error:
Cannot access class 'MyAvroObject.Builder'. Check your module classpath for missing or conflicting dependencies
I am able to access other MyAvroObject variables. More precisely, methods such as
val schema = MyAvroObject.getClassSchema()
val decoder = MyAvroObject.getDecoder()
compiles fine. What makes it even stranger is that I can access newBuilder() in my test/ folder, but not in my src/ folder.
Why do I get a compile error when using newBuilder()? Is the namespace of the avro-schema used to generate MyAvroObject of importance?
Check your module classpath generally means, that your dependencies (which you didn't provide) are messed up. One of them should read implementation instead of testImplementation, in order to have the method available in the main source-set, instead of only the test source-set - but this may well have to do with the input classes, the output location of generated classes, or annotations alike #VisibleForTesting (just see what it even generates). Command gradlew can also list the dependencies per configuration. The builder seems to be called org.apache.avro.SchemaBuilder... there's only avro-1.11.0.jar & avro-tools-1.11.0.jar. With the "builder" design pattern, .newBuilder() tries to return inner class Builder.
had the same problem today and was able to solve it by adding the following additional source folder
<sourceDir>${project.basedir}/target/generated-sources/avro</sourceDir>
to the kotlin-maven-plugin.

Create multiple bundles for different interface implementations

I would like to achieve the following in a project where I'm using browserify:
I would like to generate 2 different bundles from the same sources, each one including a given implementation of a common interface,
requires requires generates
a.js +------------> b.js +------------> c.impl1.js +-----------> bundle.1.js
|
+------------> c.impl2.js +-----------> bundle.2.js
How should I require the different implementations from the b.js file and configure browserify to not to end up with a single bundle with all the dependencies included?
Thanks in advance!
I found out a solution while looking to some unrelated code.
I'm now using this pattern to create an intermediate interface file c.js:
if (process.env.CLASS_IMPL === 'impl1') {
module.exports = require('./c.impl1')
} else {
module.exports = require('./c.impl2')
}
So I export one or other implementation depending on an environment variable I set before running the bundling process.

Using Db::getInstance() in a CLI script

I've been wanting to create a add-on cron script that utilises Prestashop's DB class instead of instantiating the database handle directly, but I can't seem to figure out where did the "Db" class commonly referenced by "Db::getInstance()" calls get defined.
classes/Db.php defines an abstract DbCore class. MySQLCore extends Db as you can see, however Db is never defined anywhere:
[/home/xxxx/www/shop/classes]# grep -r "extends Db" ../
../classes/MySQL.php:class MySQLCore extends Db
According to another thread on Prestashop forums, the abstract DbCore class is implemented in a class located in override/classes/db, however that directory does not exist.
[/home/xxxx/www/shop/override]# cd ../override/
[/home/xxxx/www/shop/override]# ls
./ ../ classes/ controllers/
[/home/xxxx/www/shop/override]# cd classes/
[/home/xxxx/www/shop/override/classes]# ls
./ ../ _FrontController.php* _Module.php* _MySQL.php*
Our shop is working, so obviously I am missing something. We are running Prestashop 1.4.1, so perhaps the docs are no longer applicable.
Quite clearly in many places in the code base functions from the Db class are being used, but this last grep through the code found nothing:
grep -rwI "Db" . | grep -v "::"
./modules/productcomments/productcommentscriterion.php:require_once(dirname(__FILE__).'/../../classes/Db.php');
./classes/MySQL.php:class MySQLCore extends Db
./classes/Db.php: * Get Db object instance (Singleton)
./classes/Db.php: * #return object Db instance
./classes/Db.php: * Build a Db object
Is there something I am missing? Where did this magical Db class come from?
To create a CLI script, the easiest way is to include the config file so you will have access to every classes. For example
<?php
require dirname(__FILE__).'/config/config.inc.php'; // assuming your script is in the root folder of your site
// you can then access to everything
$db = Db::getInstance();
You are confused a little bit with this. In PS 1.4.x. in the override directory, no files are palced. The documentation is following PS 1.5.x.
PS is using autoload feature to load classes. Lets take DB class as an example. The file name is Db.php , but class name is DbCore and when we want to get object of Db class, we do it like
Db::getInstance();
means not like
DbCore::getInstance();
How this works ? The thing is the php auto load function. Checkout the config/autoload.php (or a file with a name like that), and you will see that PS checking the class with and without Core at the end of the class name. Means that if the a name has Core or not, it will be loaded.
Starting with PS 1.5.x , PS placed over rided files in override/classes folder. Please note that all those classes are extending their respective classes. For example in override/classes/db the class Db.php is placed and this file has only the following code
<?php
abstract class Db extends DbCore
{
}
So it is clear if we want to use Db class, it will call the override/classes/db/Db.php which is extended from DbCore class.
Similarly for all other classes, the same criteria is used.
I hope those details will help.
Thank you

Specify path of a file in a Class Library, a method in that class library called from console application

I have a ClassLibrary Project which is my business layer - Demo.Business
For this class library,
I have folder in the class library as below
TRT
|
TRT.cs
TRTDetails.cs
TRTFiles(Folder)
|
**TRTFile.txt**
In TRT.cs class i have a method
public void UpdateDetails()
{
var typeSeq = from val in TRTDetails.Read**(#"TRTFile.txt")**
}
Now i have added reference of this class library "Demo.Business.dll" to my console application - "DemoProcess.exe".
In the above Console Application I am calling the method "UpdateDetails()" as follows:
public void CallMethod()
{
UpdateDetails();
}
How can I specify the path of the file "TRTFile.txt" in the method "UpdateDetails()" in class library?
I tried using System.IO.Path.GetDirectoryName
(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
Which always gives the path of executing application.
i.e
C:\\Projects\\Demo.Process\\bin\\Debug
How can i get the path as
C:\\Projects\\Demo.Business\\TRT\\TRTFiles............
There are two ways to do this:
I.
This can be done using relative path. If your's dll is also situated in Debug folder, the following path = #"..\..\..\Demo.Business\TRT\TRTFiles\" will do the work.
First ..\ will get us to C:\\Projects\\Demo.Process\\bin\\.
Second ..\ will get us to C:\\Projects\\Demo.Process\\.
Third ..\ will get us to C:\\Projects\\.
II.
Or by using classes used for writing visual studio extensions (Extensibility, EnvDTE namespaces, etc.), they provide functionality to get all information about your project and it's content. But it's complicated.