Use Proguard 5.3 ,default type methods change to public type - proguard

I want to develop a private SDK(a jar file),some method is default permission,i want it can be called in current package only,like this:
/* package */
static String getApplicationId() {
return mApplicationId;
}
but,when use proguard to make jar later,this method change to public type,and the method name like this:
public static String c() {
return sApplicationId;
}
so i want know how to config proguard file.to make default permission method can't visiable when use this jar by proguard later,thanks

You should check your configuration, most likely you have the following setting enabled:
-allowaccessmodification
When obfuscating a library, you normally do not want this enabled, as you experience the effects as described in the question.

Related

How to use WebApplicationFactory in .net6 (without speakable entry point)

In ASP.NET Core 6 default template moves everything from Sturtup.cs into Program.cs, and uses top-level statements in Program.cs, so there's no more (speakable) Program class ether.
That looks awesome, but now, I need to test all of this. WebApplicationFactory<T> still expects me to pass entry-point-class, but I cannot do this (due to it's name now being unspeakable).
How integration tests are expected to be configured in ASP.NET Core 6?
Note that if you are trying to use xUnit and its IClassFixture<T> pattern, you will run into problems if you just use the InternalsVisibleTo approach. Specifically, you'll get something like this:
"Inconsistent accessibility: base class WebApplicationFactory<Program> is less accessible than class CustomWebApplicationFactory."
Of course you can solve this by making CustomWebApplicationFactory internal but it only moves the problem as now your unit test class will give the same error. When you try to change it there, you will find that xUnit requires that tests have a public constructor (not an internal one) and you'll be blocked.
The solution that avoids all of this and allows you to still use IClassFixture<Program> is to make the Program class public. You can obviously do this by getting rid of the magic no class version of Program.cs, but if you don't want to completely change that file you can just add this line:
public partial class Program { } // so you can reference it from tests
Of course once it's public you can use it from your test project and everything works.
As an aside, the reason why you typically want to prefer using IClassFixture is that it allows you to set up your WebApplicationFactory just once in the test class constructor, and grab an HttpClient instance from it that you can store as a field. This allows all of your tests to be shorter since they only need to reference the client instance, not the factory.
Example:
public class HomePage_Get : IClassFixture<CustomWebApplicationFactory>
{
private readonly HttpClient _client = new HttpClient();
public HomePage_Get(CustomWebApplicationFactory factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task IncludesWelcome()
{
HttpResponseMessage response = await _client.GetAsync("/");
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
Assert.Contains("Welcome.", stringResponse);
}
}
Finally note that Damian Edwards' MinimalAPIPlayground was updated to use this approach after we discussed the issue. See this commit
The problem is was solved on ASP.NET Core RC1, but as of now (September 20, 2021) the docs are incomplete.
The compiler generates a Program class behind the scenes that can be used with WebApplicationFactory<>. The class isn't public though so the InternalsVisibleTo project setting should be used.
Damien Edwards' Minimal API sample uses the latest nightly bits. The test web app class is declared as :
internal class PlaygroundApplication : WebApplicationFactory<Program>
{
private readonly string _environment;
public PlaygroundApplication(string environment = "Development")
{
_environment = environment;
}
protected override IHost CreateHost(IHostBuilder builder)
{
...
In the application project file,InternalsVisibleTo is used to make the Program class visible to the test project:
<ItemGroup>
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
</ItemGroup>
RC1 is feature complete and, judging by previous major versions, it will probably be the first version to have a Go Live license, which means it's supported in production.
I tried
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
but no cigar! Removed it and added a partial class to program.cs
#pragma warning disable CA1050 // Declare types in namespaces
public partial class Program
{
}
#pragma warning restore CA1050 // Declare types in namespaces
amazingly it worked.

org.jetbrains.annotations.NotNull instead of javax.annotation.Nonnull when implement method in Intellij IDEA

After recent JetBrains Intellij IDEA updates I found out that when I'm trying to implement method annotated with javax.annotation.Nonnull - IDE implements it with org.jetbrains.annotations.NotNull instead.
Example:
If you have an interface:
import javax.annotation.Nonnull;
interface User {
#Nonnull
String getName();
}
it will be implemented as:
import org.jetbrains.annotations.NotNull;
class Customer implements User {
#NotNull
#Override
public String getName() {
return null;
}
}
The question is how to configure IDE to implement methods with strict validation annotation?
Looks like a defect (https://youtrack.jetbrains.com/issue/IDEA-253324) although there is a workaround exist:
Inspections > Java > Probable bugs > Nullability problems > #NotNull/#Nullable problems > Configure Annotations. Set javax.annotation.Nullable/javax.annotation.Nonnull as defaults and restart the IDE.
To add the library with annotations to a Gradle project, add the implementation org.jetbrains:annotations:23.0.0 dependency to the build.gradle file.

TYPO3 extbase: get some from FrontendUserGroupRepository

In a class file I can get all records from another repository that is not mine
$allUsergroups = $this->feGroupRepository->findAll();
How to make custom function to acomplish something like this on such a repository in the most correct way?
// magic default function that takes a uid list (or array) as argument
$someUsergroups = $this->feGroupRepository->findSomeByUidList('2,4,6,8');
Or can I extent an existing repository with my own custom functions, in this case based on $query->in(list)?
You can create your own method in your extensionRepository.php class
you can use :
in($propertyName, $operand)
or
contains($propertyName, $operand)
Contrarily, the methods in() and contains() accept multi-value data types as arguments (e.g. Array, ObjectStorage).
take a look how some other extension are doing stuff. (like the tx_news extension)
or read some docs here :
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/3-implement-individual-database-queries.html
Yes, you can extend another class in TYPO3 without any need to change any other code. It´s called Dependency Injection in ExtBase context.
First, create a new repository class your_ext/Classes/Domain/Repository/FrontendUserRepository.php and add below content to it:
<?php
namespace Tillebeck\YourExt\Domain\Repository;
class FrontendUserRepository extends \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository {
/**
* #param array $uidList
* #return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
public function findByUidList(Array $uidList)
{
$query = $this->createQuery();
//$query->getQuerySettings()->setRespectStoragePage(false);
$query->matching(
$query->in('uid', $uidList)
);
return $query->execute();
}
/**
* #return string
*/
protected function getRepositoryClassName()
{
return get_parent_class($this);
}
}
Here we have implemented your method findByUidList with the required argument $uidList which needs to be an array.
Because repositories resolve their model names by their own class name, we need to change the method getRepositoryClassName to return the parent class name, in this case TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository.
But this alone won't work. We need to tell ExtBase that every time we inject or initialize a TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository, either by PHPDocBlock annotation #inject or by the objectManager->get, then we really want to initialize our new repository. This is done in TypoScript.
config.tx_extbase.objects {
TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository {
className = Tillebeck\YourExt\Domain\Repository\FrontendUserRepository
}
}
You can also restrict your change to your own extension alone by replacing config.tx_extbase with plugin.tx_yourext.
Last step: clear ALL cache, and possibly delete all files in typo3temp directory.
Now in your controller (or other class) you can run below code.
$uidList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', '2,4,6,8', true);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(
$this->frontendUserRepository->findByUidList($uidList)
);
I have tested above solution in TYPO3 7.6 and it works. Dependency Injection has existed since version 6.1.
This is by my definition the must correct way, as you asked, to implement this feature in your own TYPO3 extension.

How to inject a custom (non-bean) value to JAX-RS resources?

With following JAX-RS resource class,
#Path("/myresource")
class MyResource {
#GET
public Response readSomeValue() {
// ...
}
#Inject
private int someValue;
}
How can I inject someValue?
I'm using org.glassfish.jersey.bundles:jaxrs-ri with Spring on Apache Tomcat. No EJBs.
I, so far, found this.
/**
* Is this gonna work?
*/
class SomeValueProducer {
#Produces
public int produceSomeValue() {
/// ...
}
}
Is this the only way? Using #Procudes?
Where can I place the producer class? Just alongside the resource class?
Do I need a beans.xml?
Do I need a qualifier annotation?
Thanks.
Is this the only way? Using #Procudes?
Yes
Where can I place the producer class? Just alongside the resource class?
doesnt matter, every jar with a valid beans.xml should be scanned from the framework if configured correct: including every package in your project.
Do I need a beans.xml?
yes
Do I need a qualifier annotation?
yes, without a qualififer every method which returns an int value is a possible source for an injection.

Maven plugin complex parameter initialization via system properties

I need to run maven plugin from console. In plugin i need a complex parameter kind of:
/**
* #goal do-automation
**/
public class AutomationMojo extends AbstractMojo {
/**
* The current maven project.
*
* #parameter expression="${project}"
*/
protected MavenProject project;
/**
* App configuration.
*
* #parameter expression="${appConfig}"
*/
private AppConfig appConfig;
AppConfig parameter looks smth like this:
public class AppConfig {
private String path
private String version
}
I will be running maven plugin in the following way:
mvn group:artifact:version:do-automation -Dproperty.for.appConfig
How can i set AppConfig properties via system properties? It is possible?
i tried the following and it didn't work for me:
public class AppConfig {
/**
* #parameter expression="${path}"
*/
private String path
private String version
}
mvn group:artifact:1.0-SNAPSHOT:do-automation -DappConfig.path=122 -Dpath=122
It created AppConfig with null values for properties
I am using:
Apache Maven 2.2.1 (r801777; 2009-08-06 14:46:01-0430)
Java version: 1.6.0_21
Java home: c:\Program Files\Java\jdk1.6.0_21\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7" version: "6.1" arch: "x86" Family: "windows"
Actually Maven 3 provides some other means to do what you want. Please, have a look to this link, section (Bean Default Properties)
http://blog.sonatype.com/people/2011/03/configuring-plugin-goals-in-maven-3/
You can define set(String configStr) method in your AppConfig and parse string passed from command line. For Instance.
mvn group:artifact:1.0-SNAPSHOT:do-automation -DappConfig=my/path,version
Then you will be able to parse "my/path,version" in the set(...) method appropriately.
you have read this already. Here is an excerpt:
configuration #parameter expression="${aSystemProperty}"
default-value="${anExpression}"
Specifies the expressions used to calculate the value to be injected
into this parameter of the Mojo at buildtime. The expression given by
default-value is commonly used to refer to specific elements in the
POM, such as ${project.resources}, which refers to the list of
resources meant to accompany the classes in the resulting JAR file. Of
course, the default value need not be an expression but can also be a
simple constant like true or 1.5. And for parameters of type String
one can mix expressions with literal values, e.g.
${project.artifactId}-${project.version}-special. The system property
given by expression enables users to override the default value from
the command line via -DaSystemProperty=value. NOTE: If neither
default-value nor expression are specified, the parameter can only be
configured from the POM. The use of '${' and '}' is required to
delimit actual expressions which may be evaluated.
you should change your configuration like the following:
/**
* App configuration.
*
* #parameter
*/
private AppConfig appConfig;
public class AppConfig {
/**
* #parameter expression="${appConfig.path}"
*/
private String path
/**
* #parameter expression="${appConfig.version}*/
private String version
}
This should give the opportunity to use your system configuration arguments. First i would check if the configuration via usual configuration tag for a plugin works as expected to see if something different is wrong.