У меня есть многомодульный проект Maven со следующей структурой
Foo
|_ Bar
| |_ src/main/java/bar/BarClass.java
| |_ pom.xml
|
|_ Baz
| |_ src/main/java/baz
| |_ pom.xml |_ BazClass.java
| |_ SerializablePlugin.java
|_ pom.xml
Модуль Baz использует плагин Byte Buddy для добавления интерфейса к BazClass
как части сборки Maven. Для этого примера я выбрал Serializable
.
package baz;
public class BazClass // Serializable will be added by Byte Buddy
{
}
Модуль Bar зависит от Baz, чтобы использовать BazClass
.
package bar;
import baz.BazClass;
import java.io.Serializable;
public class BarClass
{
public static void main(String[] args)
{
Serializable serializable = new BazClass();
}
}
Это прекрасно компилируется с Maven - глядя на декомпилированный файл класса, я вижу, что интерфейс был добавлен - но IntelliJ сообщает об ошибке, потому что не знает об изменении.
Incompatible types.
Required: java.io.Serializable
Found: baz.BazClass
Так что я могу только сделать вывод, что для принятия этого решения он должен смотреть на исходный файл, а не на скомпилированный файл класса.
Можно ли изменить настройку IntelliJ, чтобы она смотрела на определение в файле класса, а не в исходном файле? Если бы это не был многомодульный проект, и я извлекал JAR из хранилища, у меня не было бы этой проблемы.
Я бы предпочел не менять сборку только из-за проблемы, связанной с IDE.
Ниже приведены остальные POM и классы, не показанные выше, если вы хотите попытаться воспроизвести. Извиняюсь, что это не короче; Я максимально уменьшил его, но POM многословны.
Foo
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>foo</groupId>
<artifactId>foo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<modules>
<module>bar</module>
<module>baz</module>
</modules>
</project>
Бар
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>foo</artifactId>
<groupId>foo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bar</artifactId>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>baz</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Баз
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>foo</artifactId>
<groupId>foo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>baz</artifactId>
<dependencies>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.9.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-maven-plugin</artifactId>
<version>1.9.12</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformations>
<transformation>
<plugin>baz.SerializablePlugin</plugin>
</transformation>
</transformations>
</configuration>
</plugin>
</plugins>
</build>
</project>
Plugin
package baz;
import net.bytebuddy.build.Plugin;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import java.io.Serializable;
public class SerializablePlugin implements Plugin
{
@Override
public DynamicType.Builder<?> apply(final DynamicType.Builder<?> builder,
final TypeDescription typeDescription,
final ClassFileLocator classFileLocator)
{
return builder.topLevelType().implement(Serializable.class);
}
@Override
public boolean matches(final TypeDescription target)
{
return target.getSimpleName().equals("BazClass");
}
@Override
public void close()
{
// not required
}
}