Scala publi c становится приватным при доступе из Java? - PullRequest
2 голосов
/ 07 февраля 2020

Я довольно знаком с Java и Maven , но совсем не знаком с Scala. Я пытаюсь получить доступ к Scala из Java, и одна из проблем, которые я не могу понять, заключается в следующем:

Мой вопрос

В AccessScala.java Я пытаюсь получить доступ к переменной в WithinModule.scala:

package me.parent.jModule;

public class AccessScala{
    public static void main(String[] args){
        WithinModule within = new WithinModule();
        // -- this is like a static variable
        System.out.println(WithinModule.string);
        // -- this is like an instance variable
        System.out.println(within.string);
        // -- this is a getter, as it should be in Java
        System.out.println(within.getString());
    }
}

Эта переменная должна быть опубликована c

package me.parent.jModule;

class WithinModule{
  val string : String = "this is the local scala string";
}

Но при запуске mvn clean package он говорит мне, что эта переменная является личной:

[ERROR] [Error] C:\projectLocation\parent\jModule\src\main\java\me\parent\jModule\AccessScala.java:7: string has private access in me.parent.jModule.WithinModule
[ERROR] [Error] C:\projectLocation\parent\jModule\src\main\java\me\parent\jModule\AccessScala.java:9: string has private access in me.parent.jModule.WithinModule

По сути, я неправильно понимаю, как это должно работать, или я делаю что-то не так?

Настройка проекта

Я поднял проект на GitHub , с кратким описанием того, что может быть уместно здесь. Файлы организованы примерно так:

> parent
 | > jModule
 | | > src/main
 | | | > java/me/parent/jModule
 | | | | > AccessScala.java
 | | | > scala/me/parent/jModule
 | | | | > WithinModule.scala
 | | > pom.xml
 | > sModule
 | | > src/scala/me/parent/sModule
 | | | >ExternalModule.scala
 | | > pom.xml
 | > pom.xml

Я взял своего родителя pom.xml в основном из здесь . С некоторыми модификациями это закончилось как ниже. Эта точная настройка отлично работает в другом проекте, где был (пока) только один случай, когда Java использовал класс, написанный в Scala, но с большим количеством кода на обоих языках. Тестирование и все работало нормально, пока мы не попытались получить доступ к val с Scala в пределах Java.

Я использую компилятор Maven , surefire и failsafe плагины для компиляции и тестирования Java (тестов пока нет) и Scala -Maven и ScalaTest плагины для компиляции и тестирования Scala кода (также пока нет тестов). Они настроены на компиляцию и тестирование сначала Scala, а затем переходят к Java.

<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>me</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.13.1</version>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_2.13</artifactId>
            <version>3.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- stuff for compiling and testing Java during `mvn package` -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
            <!-- This is for Scala compilation during `mvn package` -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>4.3.1</version>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <!--
            <execution>
              <id>scala-test-compile</id>
              <phase>process-test-resources</phase>
              <goals>
                <goal>testCompile</goal>
              </goals>
            </execution>
            -->
                </executions>
            </plugin>
            <plugin>
                <groupId>org.scalatest</groupId>
                <artifactId>scalatest-maven-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
                    <junitxml>.</junitxml>
                    <filereports>WDF TestSuite.txt</filereports>
                </configuration>
                <executions>
                    <execution>
                        <id>test</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <modules>
        <module>jModule</module>
        <module>sModule</module>
    </modules>
</project>

PS

Будем благодарны за любые предложения о том, что происходит. Как я уже упоминал, я пытаюсь заставить Java и Scala работать вместе, что, как я слышал, должно быть довольно простым, но я продолжаю сталкиваться с проблемами, это одна из них.

1 Ответ

1 голос
/ 07 февраля 2020

Анализируя scalac -print вывод, мы видим, что

class WithinModule {
  val string : String = "this is the local scala string"
}

расширяется до чего-то вроде

  class iw$WithinModule extends Object {
    private[this] val string: String = _;
    <stable> <accessor> def string(): String = iw$WithinModule.this.string;
    def <init>(): $line184.iw$WithinModule = {
      iw$WithinModule.super.<init>();
      iw$WithinModule.this.string = "this is the local scala string";
      ()
    }
  }

, где мы отмечаем def string(): String, поэтому в AccessScala.java try

WithinModule within = new WithinModule();
System.out.println(within.string());
...