Im trying to implement the simple server-client application using scalaPB's official example. The scala code is found on their gitHub
However, when I try to run it, I keep getting the error object helloworld is not a member of package io.grpc.examples.helloworld when I try to import anything using import io.grpc.examples.helloworld.helloworld.{foo}.
My build.sbt file:
name := "Distributed sorting"
version := "0.1"
scalaVersion := "2.13.7"
libraryDependencies ++= Seq(
"io.grpc" % "grpc-netty" % scalapb.compiler.Version.grpcJavaVersion,
"com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion
)
Compile / PB.targets := Seq(
scalapb.gen() -> (Compile / sourceManaged).value / "scalapb"
)
My files look like this:
├── build.sbt
├── project
│ ├── build.properties
│ ├── scalapb.sbt
│ └── target
├── ...
└── src/main
├── protobuf
├── hello.proto
└── scala/io/grpc/examples/helloworld
├── HelloWorldClient.scala
└── HelloWorldServer.scala
Firstly, I recommend using Akka gRPC rather than using ScalaPB directly. The documentation is pretty clear and there is a giter8 config that can be used to create a sample project using sbt new.
Secondly, the code in that gitHub does not look like official sample code. It says it has been "translated from grpc java" which is probably not what you want.
Finally, on the specific issue you are seeing, the stubs generated by scalaPB are in a package whose name is given in the proto file. The example file has
package com.example.protos
So the stubs will be in com.example.protos.Greeter.
Related
I have an existing scala project using SBT which has several modules.
I'd like to start adding new modules in kotlin - I don't require the ability to add kotlin to existing modules (but it could be nice if possible)
I can create new dedicated modules for the new kotlin code if that is a necessity as long as it is possible for the existing scala code to call out to the newly added kotlin modules (visa versa is nice to have but can live without that "kotlin calling scala" if impossible to do that)
Is this feasible and practical thing to do? If possible, how would this be done?
.
├── build.sbt
............
├── Module1ScalaWithJava (EXISTING)
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ ├── resources
│ │ │ └── scala
├── Module2ScalaOnly (EXISTING)
│ ├── src
│ │ ├── main
│ │ │ └── scala
│ │ └── test
│ │ └── scala
├── NewModuleKotlinOnly (I WANT THIS)
│ ├── src
│ │ ├── main
│ │ │ └── ???KOTLIN????
As mentioned in comments, you can add kotlin module using kotlin-plugin.
Add line to your project/plugins.sbt file (or create it):
addSbtPlugin("com.hanhuy.sbt" % "kotlin-plugin" % "2.0.0")
And you will be able to add kotlin modules to your sbt-project. I would advice you using only build.sbt file for adding modules. I will demonstrate you how to do that below.
I created simple multi-module project with scala and kotlin modules which are depends on each other.
Here my build.sbt:
name := "kotlin-scala"
version := "0.1"
scalaVersion := "2.13.4"
lazy val scalaFirst =
project
.in(file("scala-first"))
lazy val kotlinFirst =
project
.in(file("kotlin-first"))
.settings(
libraryDependencies ++= Seq(
"org.junit.jupiter" % "junit-jupiter-api" % "5.7.0"
).map(_ % Test)
)
lazy val scalaSecond =
project
.in(file("scala-second"))
.dependsOn(kotlinFirst % "compile->compile;test->test")
.settings(
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.3"
).map(_ % Test)
)
lazy val kotlinSecond =
project
.in(file("kotlin-second"))
.dependsOn(scalaFirst % "compile->compile;test->test")
.settings(
libraryDependencies ++= Seq(
"org.junit.jupiter" % "junit-jupiter-api" % "5.7.0"
).map(_ % Test)
)
lazy val kotlinScalaSubmodule =
project
.in(file("kotlin-scala-submodule"))
.dependsOn(kotlinFirst % "compile->compile;test->test")
.dependsOn(scalaFirst % "compile->compile;test->test")
.settings(
libraryDependencies ++= Seq(
"org.junit.jupiter" % "junit-jupiter-api" % "5.7.0"
).map(_ % Test)
)
lazy val scalaKotlinSubmodule =
project
.in(file("scala-kotlin-submodule"))
.dependsOn(scalaFirst % "compile->compile;test->test")
.dependsOn(kotlinFirst % "compile->compile;test->test")
.settings(
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.3"
).map(_ % Test)
)
build.properties contains:
sbt.version = 1.3.2
My project structure:
Here I have some dependencies between modules:
+---------------+ +--------------+
| kotlin-first | | scala-first |
+---------------+ +--------------+
^ \ / ^
| \/ |
+--------------+ || +---------------+
| scala-second | || | kotlin-second |
+--------------+ || +---------------+
||
/ \
+------------------+ +------------------+
| scala-kotlin-sub | | kotlin-scala-sub |
+------------------+ +------------------+
full project you can find on github
Also I write just some unit-tests to demonstrate that it works properly.
Tested on:
java open-jdk 1.8,
scala version 2.13.4.
sbt version 1.3.2
Intellij IDEA build 2020.2.3 with jetBrains scala plugin works properly with this project.
I'm trying to define a multi-project build with a consequent number of subprojects:
.
├── build.sbt
├── project/
│ ├── dependencies.scala
│ ├── tasks.scala
│ └── settings.scala
├── lib_1/
│ └── src/
├── ...
└── lib_n/
└── src/
Those subprojects are currently defined in build.sbt:
val outputJarFolder = "/some/path/"
lazy val comonSettings = /* ... */
lazy val lib_1 = (project in file ("lib1")).settings(
name:="LibOne",
commonSettings,
libraryDependencies ++= Seq(scalaTest, jsonLib, scalaXML, commonsIo),
Compile/packageBin/artifactPath := file(outputJarFolder + "lib1.jar")
)
// ... more libs ...
lazy val lib_n = (project in file ("libn")).settings(
name:="LibLast",
commonSettings,
Compile/packageBin/artifactPath := file(outputJarFolder + "libn.jar")
)
.depensOn(lib_2, lib_12)
How can I define those subprojects in another file than build.sbt in order to "unclog" that file? I want to still be able to define them in their lexicographic order (so lazy is a must). I'm working with sbt version 1.2.8 and scala 2.10.
I've tried:
Putting the declaration of those lib_k variables in a scala file and importing it --> sbt says: "classes cannot be lazy".
Putting those declaration in an object (or in a class and instantiate it in build.sbt) --> sbt projects doesn't list any subproject.
sbt documentation mentions it, but doesn't emphasize too much (perhaps to avoid encouragement for too much variation in how builds are defined in the absence of a common convention):
The build definition is described in build.sbt (actually any files named *.sbt) in the project’s base directory.
So you can split your build.sbt file into several separate .sbt files in the root of the project with different names.
I also recommend reading documentation on Organizing the build.
I am learning Scala with this coursera course task here that provides SBT file. I download its objsets.zip here. Then I unzip it end and enter into it and type sbt and then console. I try to load the file src/main/scala/objsets/TweetSet.scala on commandline but I am getting a lot of errors.
scala> :load src/main/scala/objsets/TweetSet.scala
Loading src/main/scala/objsets/TweetSet.scala...
<console>:1: error: illegal start of definition
package objsets
^
<console>:10: error: not found: value TweetReader
import TweetReader._
^
import common._
defined class Tweet
<console>:2: error: illegal start of statement (no modifiers allowed here)
override def toString: String =
^
the course uses Eclipse Scala IDE but I would like to learn to use Vim for Scala development, my favorite editor. I find Eclipse hard to use. So
How can I load the scala files in the scala interpreter on the commandline under SBT? Does there exist some favourable tools for developing the scala project on a text editor such as Vim without having to leave the editor or commandline themselves?
SBT files and the directory looks like this
$ tree src/
src/
├── main
│ └── scala
│ ├── common
│ │ └── package.scala
│ └── objsets
│ ├── TweetData.scala
│ ├── TweetReader.scala
│ ├── TweetSet.scala
│ └── testing.sc
└── test
└── scala
└── objsets
└── TweetSetSuite.scala
7 directories, 6 files
$ cat build.sbt assignment.sbt
name := course.value + "-" + assignment.value
scalaVersion := "2.11.7"
scalacOptions ++= Seq("-deprecation")
// grading libraries
libraryDependencies += "junit" % "junit" % "4.10" % Test
// for funsets
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4"
// include the common dir
commonSourcePackages += "common"
courseId := "bRPXgjY9EeW6RApRXdjJPw"
course := "progfun1"
assignment := "objsets"
assignmentInfo := AssignmentInfo(
key = "6PTXvD99EeWAiCIAC7Pj9w",
itemId = "d1FGp",
premiumItemId = Some("Ogg05"),
partId = "7hlkb",
styleSheet = Some((_: File) / "scalastyle" / "scalastyle_config.xml")
)
:load copies the contents of a file into the REPL line by line. That means that you end up trying to define a package (which is not allowed in the REPL), and then you try to import things that aren't visible, etc. If you use :load on a file that has a format useable by the REPL, it will work. In most cases, this means replacing the package line(s) with imports.
There's no need to use :load anyway. sbt console will place you in a REPL that has the project on its classpath. sbt consoleQuick will place you in a REPL that only has the dependencies on the classpath.
For your second question, you are meant to use sbt as a background process. In your terminal emulator, you'll have one tab running vim on your files, and in the other tab, you'll have sbt. In the tab with sbt, you can run ~compile, which recompiles your code every time you save a file in Vim. This replicates how IDEs show compiler errors/warnings as you type.
I have created a project foo_proj with Intellij (using SBT template) and added a module test_mod to it. The abbreviated directory looks like this
foo_proj
├── src
│ └── main
│ └── scala-2.11
│ └── proj_obj.scala
└── test_mod
└── src
└── tmod.scala
The contents of proj_obj.scala are:
package com.base.proj
object proj_obj {
}
If would like to be able to import this object (proj_obj) into the module file tmod.scala, but when I try import com.base.proj, it can't find it.
I am new to Scala, so if I want to use stuff from the project src directory in other project modules, how else should I be structuring things? Or is this an Intellij IDEA configuration that I need to set?
Edit
The contents of the generated build.sbt are
name := "test_proj"
version := "1.0"
scalaVersion := "2.11.6"
to enable "submodules" (aka multiproject), all you need to do is add the following to your build.sbt file (or use a scala file under project dir):
lazy val root = project in file(".")
lazy val testModule = project in file("test_mod") dependsOn(root)
also, you should change test_mod dir structure.
either drop the src dir and put all your sources under the test_mod dir,
or use the sbt convention: src/main/scala or src/test/scala.
I just want to create a directory layout for my scala project with sbt and sbteclipse. Following is my sbt file.
import com.typesafe.sbteclipse.plugin.EclipsePlugin.EclipseKeys
name := "BGS"
organization := "com.example"
version := "1.0.0"
scalaVersion := "2.9.2"
scalacOptions ++= Seq("-deprecation")
EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource
EclipseKeys.projectFlavor := EclipseProjectFlavor.Scala
scalaSource in Compile <<= (sourceDirectory in Compile)(_ / "scala")
scalaSource in Test <<= (sourceDirectory in Test)(_ / "scala")
libraryDependencies += "org.scalatest" %% "scalatest" % "1.8" % "test"
libraryDependencies += "junit" % "junit" % "4.10" % "test"
unmanagedBase <<= baseDirectory { base => base / "lib" }
unmanagedJars in Compile <<= baseDirectory map { base => (base ** "*.jar").classpath }
In this sbt file, I had to use folling to lines to force creation of Scala directories:
scalaSource in Compile <<= (sourceDirectory in Compile)(_ / "scala")
scalaSource in Test <<= (sourceDirectory in Test)(_ / "scala")
Furthermore, after running "eclipse" from sbt console, I imported the project to Eclipse, but I could not create Scala class. Eclipse project icon has "J" letter attached to it indicating it is a Java project :-?
Why does sbt and sbteclipse default to Java?
I am running sbt version 0.12 (latest version as of Nov 2012), scala 2.9.2
For your information, what I am aiming to do is use sbt to create working project with following directory structure:
├── build.sbt
├── lib
│ ├── biojava3-core-3.0.4.jar
├── project
│ ├── plugins.sbt
│ ├── project
│ │ └── target
│ └── target
│ ├── config-classes
│ ├── scala-2.9.2
│ └── streams
├── src
│ ├── main
│ │ ├── java
│ │ ├── resources
│ │ └── scala
│ └── test
│ ├── java
│ ├── resources
│ └── scala
├── target
│ ├── scala-2.9.2
│ │ ├── cache
│ │ ├── classes
│ │ └── test-classes
│ └── streams
│ └── compile
└── test
Since I haven't got any desirable answers so far, I am trending into Typesafe Stack. I removed manually-installed scala and sbt and I am using everything from Typesafe Stack. I will update more when I am done testing with this way.
Here is the final update as I promised:
I followed instruction in this link and it worked perfectly:
http://typesafe.com/resources/typesafe-stack/downloading-installing.html
Detailed information in case somebody want to follow for Mac OSX:
Basically, I first I switched macport to homebrew following instruction here:
http://bitboxer.de/2010/06/03/moving-from-macports-to-homebrew/
Then I did:
brew install scala sbt maven giter8
Then create a Scala project from command line:
g8 typesafehub/scala-sbt
Finally I followed instruction here to add sbteclipse and convert the project to eclipse:
https://github.com/typesafehub/sbteclipse
Everything works as I expect.
Why do you want sbt to create those directors? why not jsut create them yourself. It's a one time event.
You shouldnt need any of the following lines
EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource
EclipseKeys.projectFlavor := EclipseProjectFlavor.Scala
scalaSource in Compile <<= (sourceDirectory in Compile)(_ / "scala")
scalaSource in Test <<= (sourceDirectory in Test)(_ / "scala")
I normally just do mkdir -p src/main/scala whenever I start a new project.