如何移除 gradle 远程依赖中多余的 package

原文链接

The exclude method of the configuration closure for a dependency excludes transitive dependencies. So, if your module dependency depends on other modules, you can exclude them from your build. You can check out the transitive dependencies of the 'com.facebook.android:facebook-android-sdk:4.14.0' module on its Maven repository info page.

If the BundleJSONConverter class exists in a transitive dependency, you can exclude the specific module in the same way you are trying now. Just specify the group, the module and the version, like you do for dependencies.

If you just want to exclude one class for a dependency jar, take a look at the jar jar links tool and its Gradle plugin. It allows you to alter included jars, e.g. to change packages or remove classes.

The following (shortened) example shows the usage of the plugin and some methods to alter the dependency jar:


apply plugin: 'org.anarres.jarjar'

compile jarjar.repackage {
    from 'org.apache.hive:hive-exec:0.13.0.2.1.5.0-695'

    archiveBypass "commons*.jar"
    archiveExclude "slf4j*.jar"

    classDelete "org.apache.thrift.**"
    classRename 'org.json.**', 'org.anarres.hive.json.@1'
}

升级到 AngularCli9 后 ngx/cache 不能运行问题

关键字

"Can't resolve all parameters for MemoryCacheService"
"Can't resolve all parameters for LocalStorageService"

问题描述

升级到 AngularCli 9 之后 ngx-cache 模块加入后,运行会出现上述问题

解决方案

注入方式由

{ provide: CACHE, useClass: (MemoryCacheService) }

改为

{ provide: CACHE, useClass: (MemoryCacheService), deps: [PLATFORM_ID] }

其实就是增加了 PLATFORM_ID 作为参数

详情在 Angular 9 + Ivy #128

Portainer 添加 endPoint

portainer 添加 endpoint 有两种方式

  • 直接连接到对应的 portainer agent
  • 使用 edge agent 代理连接

直连模式

使用这个模式,需要机器有公开的 9000 端口(非9000也可以,自己改),然后 portainer 会直接尝试连接机器上的 portainer agent
这个模式下,可以获得 portainer 所有功能

代理模式


这个模式下,是在机器上部署一个 edge 代理,然后这个代理自己连接到 portainer 上。这个模式就不需要机器公开任何接口,会方便不少。
但是目前发现一个功能不能使用,就是下图中的 ServiceHook

这个功能对于 ci/cd 继承自动化发布来说很好用,要是用不到可以无视。

注意点

建议都使用 swarm 模式,不然 stack 只能支持到 version 2 版本,conf 和 serect 功能也不能使用。

小结

优先使用 agent 模式,如果不能暴露端口,比如家里网络,就要使用 edge agent 模式

Homebrew 安装软件后路径配置

所有 Homebrew 安装的软件其实都会在 /usr/local/opt/ 这个地方创建一个软应用,指向的都是当前命令使用的软件版本,比如我虽然安装了两个 git,一个24版本,一个26版本,命令行可以使用的是26版本 ,所以这个路径 /usr/local/opt/git/bin/git的版本就是 26 版本。
这种目录最常见用于配置 IDE 各种环境的路径,比如说 git

相较于以前直接配置到具体版本的路径上,每次升级都要改,这个要方便不少。

Docker Swarm Volume 问题记录

Docker Swarm 或者 Docker Compose 部署的容器有个问题,如果你使用的是 Docker 自动创建的 Volume ,也就是这种方式

version: '3'

services:
  caddy:
    image: jayfong/caddy-dnspod
    environment:
    volumes:
      # Caddy 自动生成的 SSL 证书
      - certs:/caddy/certs
    ports:
      - 2015:2015
    restart: unless-stopped
volumes:
  certs:

这个 Volume 最终的名字是 caddy-home_cert ,因为我指定的 docker stack 名字为 caddy-home, 如果你下次更新,就必须要指定一样的名字,不然是不能到达一样的文件目录的。如果确实不能弄成一样的名字,又不想挪动文件,其实还是有办法的,可以尝试这样写

volumes:
  certs:
    external: true

这样 docker 就不会尝试创建 certs 了 ,但是注意的是,这个东西需要提前创建好,不然是会服务部署失败的

Dagger does not support injection into private fields

这是因为在 Kotlin 中,Field 生成的 Java 代码都是都是带 getset 的,然后 Field 是要设置为 private 的,下面就是生成的代码

@Nullable
@Inject
private volatile DispatchingAndroidInjector androidInjector;

@Nullable
   public final DispatchingAndroidInjector getAndroidInjector() {
      return this.androidInjector;
   }

   public final void setAndroidInjector(@Nullable DispatchingAndroidInjector var1) {
      this.androidInjector = var1;
   }

这种情况我们有两种方法解决

第一种,让它变回 Java 原本的样子

增加 JvmField

@Inject
@JvmField
var androidInjector: DispatchingAndroidInjector<Any?>? = null

这样生成的代码就会变成

@Inject
@JvmField
@Nullable
public volatile DispatchingAndroidInjector androidInjector;

这样就完全没有问题了,但是这样会把属性暴露出去,不是很好。因为kotlin是没有包内属性的,你也改不了为包内属性。

第二种,设置 set 方法为 Inject

以为 dagger 是支持注入方法的,直接标记属性的 setter 方法也能解决这问题,代码如下

@Volatile
@set:Inject
var androidInjector: DispatchingAndroidInjector<Any?>? = null

对应的 Java代码就会变成这样

   @Nullable
   private DispatchingAndroidInjector androidInjector;

   @Nullable
   public final DispatchingAndroidInjector getAndroidInjector() {
      return this.androidInjector;
   }

   @Inject
   public final void setAndroidInjector(@Nullable DispatchingAndroidInjector var1) {
      this.androidInjector = var1;
   }

这是一个比较好的实现,不会影响原有的访问域,代码编写也比较方便

这里有个小问题
如果你在 Android Studio 3.5到 3.6 编译这个代码,会报下面这个错误

An exception occurred: java.lang.IllegalArgumentException: not a > valid name: Provider

但是,用命令行编译是没有问题的,所以我把 Android Studio 升级到 4.0,重新编译之后就没有这个问题。

上面没用,乖乖用 lateinit var 啥事都没有