使用 Ant 构建混合 Scala 和 Java 源文件的项目 - 非法循环引用错误
Building a project with mixed Scala and Java source files using Ant - illegal cyclic reference error
目前我有一个现有的 Java 项目,我正在尝试将其设置为使用混合源(Java 和 Scala)构建 Ant 构建。
我有一个 Java 接口定义为 - public interface One<T extends Two<? super T>>
当我从 Ant 构建 运行 scalac 时,我在 :
处收到以下错误
错误:涉及类型 T 的非法循环引用。
因为我希望 Scala 和 Java class 在我的项目中相互依赖,所以我首先 运行 在 运行ning javac 之前的 scalac 任务蚂蚁建造。我的 scalac 块如下所示:
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
</scalac>
有什么办法解决这个问题吗?我无法修改 Java 代码,因为有大量其他代码使用它。
我正在使用 Java 7 和 Scala 2.11.5
这是我最后看到的:
com.arif.One.java
package com.arif.java;
public interface One<T extends One<? super T>> {
void test1();
}
com.arif.Two.java
package com.arif.java;
public class Two implements One<Two> {
@Override
public void test1() {
}
}
com.arif.scala.Main.scala
package com.arif.scala
import com.arif.java.Two
object Main {
def main(args:Array[String]) {
var b:Two = null
}
}
build.xml
<property name="scala.home" value="/Users/arif/software/scala/scala-2.11.5"/>
<property name="build.classes" value="./build/classes"/>
<property name="src.path" value="src"/>
<property name="javac.target" value="1.7"/>
<property name="compile.debug" value="true" />
<property name="compile.deprecation" value="false" />
<property name="compile.optimize" value="false" />
<path id="compile.classpath">
<fileset dir="${scala.home}/lib" includes="*.jar" />
</path>
<path id="scala.classpath">
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala.home}/lib/scala-library.jar" />
<pathelement location="${scala.home}/lib/scala-reflect.jar" />
</path>
<target name="init">
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath refid="scala.classpath" />
</taskdef>
</target>
<target name="build" description="build" depends="init">
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
</scalac>
<javac srcdir="${src.path}" destdir="${build.classes}" memoryinitialsize="512m" target="${javac.target}" source="${javac.target}"
memorymaximumsize="1024m" nowarn="true" debug="${compile.debug}" deprecation="${compile.deprecation}"
optimize="${compile.optimize}" fork="true" encoding="iso-8859-1" includeantruntime="false">
<classpath refid="compile.classpath" />
</javac>
</target>
从项目根目录中的命令行 - 执行 "ant build" 给出以下 -
[scalac] Compiling 1 scala and 2 java source files to /Users/arif/rbc/scala-java/build/classes
[scalac] /Users/arif/rbc/scala-java/src/com/arif/java/One.java:3: error: illegal cyclic reference involving type T
[scalac] public interface One<T extends One<? super T>> {
[scalac] ^
[scalac] one error found
假设您在 scala 代码中做了类似的事情(因为您的 java 代码可以通过 scalac 编译):
scala> class OneImpl[T <: Two[_ >: T]] extends One[T]
<console>:15: error: illegal cyclic reference involving type T
class OneImpl[T <: Two[_ >: T]] extends One[T]
这实际上会独立于您的 Java 代码(和 Ant 本身)导致错误。我建议将其更改为:
scala> class OneImpl[Z >: T, T <: Two[Z]] extends One[T]
defined class OneImpl
无论如何,Scala 不支持循环引用。你也可以解决它(如果你真的需要这里的存在类型):
scala> class OneImpl[Z >: T, T <: Two[Z], K <: Two[_ >: Z]](implicit ev: K =:= T) extends One[T]
defined class OneImpl
看,http://www.scala-lang.org/old/node/6358
已更新。 scalac SI-4744 存在问题。它不影响所有版本,所以从一开始就没有找到它。解决方案(解决方法)是 javac
自己只编译这个接口:
javac One.java
或者类似蚂蚁的东西:
<target name="build" description="build" depends="init">
<javac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8">
<classpath refid="compile.classpath" />
<include name="**/One.java"/>
</javac>
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
<exclude name="**/One.java"/>
</scalac>
<javac>...</javac>
</target>
目前我有一个现有的 Java 项目,我正在尝试将其设置为使用混合源(Java 和 Scala)构建 Ant 构建。
我有一个 Java 接口定义为 - public interface One<T extends Two<? super T>>
当我从 Ant 构建 运行 scalac 时,我在 :
处收到以下错误错误:涉及类型 T 的非法循环引用。
因为我希望 Scala 和 Java class 在我的项目中相互依赖,所以我首先 运行 在 运行ning javac 之前的 scalac 任务蚂蚁建造。我的 scalac 块如下所示:
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
</scalac>
有什么办法解决这个问题吗?我无法修改 Java 代码,因为有大量其他代码使用它。
我正在使用 Java 7 和 Scala 2.11.5
这是我最后看到的:
com.arif.One.java
package com.arif.java;
public interface One<T extends One<? super T>> {
void test1();
}
com.arif.Two.java
package com.arif.java;
public class Two implements One<Two> {
@Override
public void test1() {
}
}
com.arif.scala.Main.scala
package com.arif.scala
import com.arif.java.Two
object Main {
def main(args:Array[String]) {
var b:Two = null
}
}
build.xml
<property name="scala.home" value="/Users/arif/software/scala/scala-2.11.5"/>
<property name="build.classes" value="./build/classes"/>
<property name="src.path" value="src"/>
<property name="javac.target" value="1.7"/>
<property name="compile.debug" value="true" />
<property name="compile.deprecation" value="false" />
<property name="compile.optimize" value="false" />
<path id="compile.classpath">
<fileset dir="${scala.home}/lib" includes="*.jar" />
</path>
<path id="scala.classpath">
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala.home}/lib/scala-library.jar" />
<pathelement location="${scala.home}/lib/scala-reflect.jar" />
</path>
<target name="init">
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath refid="scala.classpath" />
</taskdef>
</target>
<target name="build" description="build" depends="init">
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
</scalac>
<javac srcdir="${src.path}" destdir="${build.classes}" memoryinitialsize="512m" target="${javac.target}" source="${javac.target}"
memorymaximumsize="1024m" nowarn="true" debug="${compile.debug}" deprecation="${compile.deprecation}"
optimize="${compile.optimize}" fork="true" encoding="iso-8859-1" includeantruntime="false">
<classpath refid="compile.classpath" />
</javac>
</target>
从项目根目录中的命令行 - 执行 "ant build" 给出以下 -
[scalac] Compiling 1 scala and 2 java source files to /Users/arif/rbc/scala-java/build/classes
[scalac] /Users/arif/rbc/scala-java/src/com/arif/java/One.java:3: error: illegal cyclic reference involving type T
[scalac] public interface One<T extends One<? super T>> {
[scalac] ^
[scalac] one error found
假设您在 scala 代码中做了类似的事情(因为您的 java 代码可以通过 scalac 编译):
scala> class OneImpl[T <: Two[_ >: T]] extends One[T]
<console>:15: error: illegal cyclic reference involving type T
class OneImpl[T <: Two[_ >: T]] extends One[T]
这实际上会独立于您的 Java 代码(和 Ant 本身)导致错误。我建议将其更改为:
scala> class OneImpl[Z >: T, T <: Two[Z]] extends One[T]
defined class OneImpl
无论如何,Scala 不支持循环引用。你也可以解决它(如果你真的需要这里的存在类型):
scala> class OneImpl[Z >: T, T <: Two[Z], K <: Two[_ >: Z]](implicit ev: K =:= T) extends One[T]
defined class OneImpl
看,http://www.scala-lang.org/old/node/6358
已更新。 scalac SI-4744 存在问题。它不影响所有版本,所以从一开始就没有找到它。解决方案(解决方法)是 javac
自己只编译这个接口:
javac One.java
或者类似蚂蚁的东西:
<target name="build" description="build" depends="init">
<javac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8">
<classpath refid="compile.classpath" />
<include name="**/One.java"/>
</javac>
<scalac srcdir="${src.path}" destdir="${build.classes}" encoding="UTF-8" >
<classpath refid="compile.classpath" />
<include name="**/*.scala"/>
<include name="**/*.java"/>
<exclude name="**/One.java"/>
</scalac>
<javac>...</javac>
</target>