I found scalaj-collections and it looks like it's the only library that will let me convert Java.util.List to scala.collection.Seq.
Can I use this library in my Java project? Or is exclusive to Scala. I've included its dependencies in my maven pom.xml and I can use the library in my code. But I don't see how to apply the .asScala method in a Java project
Thanks
You don't need thirdparty dependencies to convert between scala and java collections. Scala library has set of adapters named JavaConversions.
Just import scala.collection.JavaConversions._ and you'll get implicit conversions between scala and java collection interfaces, so you can pass them as the arguments to functions, call scala-specific methods on java collections (and vice versa) and so on.
import scala.collection.JavaConversions._
val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl
jl.map(_ + 1)
val sl2 : scala.collection.mutable.Buffer[Int] = jl
Java.util.List to scala.collection.Seq
Scala has its own List (scala.collection.List). In addition, List has a function called toSeq(). I believe this is what you want.
Related
I want to use Runtime Reflection with Scala annotations (could also be a Java annoations if necessary, but I would prefer to limit pure Java code)
I want to implement something like:
/**
print all methods that implement a specific annotation
*/
def getAllAnnotated(): Unit {...}
For example, if I have:
class Foo {
#printme
def foo(args: A): R
def oof(args: A): R
}
class Bar {
#printme
def bar(): Unit
}
The result of running getAllAnnotated() would be something like:
Foo.foo
Bar.bar
Note that I don't want to look in a specific class, but instead any available method
Try one of classpath scanners based on Java reflection (e.g. Reflections) + scala-reflect. Since we use Java reflection only to look for classes and scala-reflect to look for annotated methods, annotations can be written in Scala.
import org.reflections.Reflections
import org.reflections.scanners.SubTypesScanner
import org.reflections.util.{ClasspathHelper, ConfigurationBuilder}
import scala.annotation.StaticAnnotation
import scala.jdk.CollectionConverters._
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.universe._
class printme extends StaticAnnotation
val reflections = new Reflections(
(new ConfigurationBuilder)
.setUrls(ClasspathHelper.forPackage(""))
.setScanners(new SubTypesScanner(false))
)
def getAllAnnotated(): Unit =
reflections.getAllTypes.asScala
.flatMap(className =>
currentMirror.classSymbol(Class.forName(className))
.toType
.decls
.filter(symbol =>
symbol.isMethod && symbol.annotations.exists(_.tree.tpe =:= typeOf[printme])
)
.map(method => s"$className.${method.name}")
).foreach(println)
Alternatives to Reflections library are for example ClassGraph and Burningwave. If we replace scala-reflect with Java reflection then annotation will have to be written in Java because only annotations written in Java are visible at runtime with Java reflection.
In Java you can scan for the classes in the package using reflection Using Reflections to get all classes of the package and then recursively go inside all the classes to find the annotations.
This is in reference to Using vals from scala package object in java
The example shows that the package object has a package declaration at the top of the file. My question is how to access it when it does not.
Example:
package object sbt {
def config(s: String): Configuration = Configurations.config(s)
}
This is found in the sbt source code. How can I access the function config from Java?
sbt.package$.MODULE$.config("abc");
figured it out :)
I am newbie in Java,
I am trying to adjust the output classes generated by JASN1 OpenMUC compiler (for java 1.5+) to run it on a BGS5 CLDC 1.1 platform.
Most basic classes have been altered and compiled successfully but there remains an issue regarding the using of parametrised List or collection class. It is used on one of basic class and used severely in most of the produced classes. and it is not supported by the CLDC 1.1 device's java libraries.
My question has two branches:
Is there any way to do the source translation from standard java to the J2ME?
How can I replace the parametrised List in the source code by a basic supported class like Vector.
A sample of a targeted class containing the parametrised List member is:
//This class file was automatically generated by jASN1 v1.6.0 (http://www.openmuc.org)
package MyPackage;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
// those packages are not available
public class DeviceInputOutputStatus {
public List<IOStatus> seqOf = null;
//IOStatus is a class of the package
public DeviceInputOutputStatus () {
seqOf = new ArrayList<IOStatus>();
}
public int encode(BerByteArrayOutputStream os) throws IOException
{
int codeLength = 0;
for (int i = (seqOf.size() - 1); i >= 0; i--) {
codeLength += seqOf.get(i).encode(os, true);
//encode is a method of IOStatus
}
return codeLength;
}
}
You will have to modify all of your generated code to not use generics. More than that, to not use any of the collections classes, since they are not supported in JavaME CLDC 1.1.
You can think of this as a two-step process. First, get rid of the use of generics. To eliminate the generics, you would use just plain List (no angle brackets following), and then add casts (from Object to IOStatus or whatever) where needed (e.g. whenever you get objects out of the list).
Step two: replace List with Vector. You will have to compare the documentation for the two classes and adjust your code accordingly.
Tip (probably you know this already): use javac's -bootclasspath option to point your compiler to the CLDC 1.1 class library to ensure that you don't use API that are not supported and -source 1.3 and -target 1.3 to ensure your source is compatible and that you produce compatible byte code.
I would like to reference a class Bag in a JAR file, but Eclipse is telling me that Bag cannot be resolved to a type. I have added the JAR in which Bag is defined to the classpath for the project, but the error is still there. What am I doing wrong?
I think you can't do that, because the Bag class in algs4.jar is inside the default package.
Before J2SE 1.4, we still can import classes from the default package using a syntax like this:
import Unfinished;
But from J2SE 1.5, that's no longer allowed. So if we want to access a default package class from within a packaged class requires moving the default package class into a package of its own. Read here for more detail explanation :
How to access java-classes in the default-package?
Some options you can choose :
Access the class via reflection or some other indirect method. But it is a little bit hard, something like this :
Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", new Class[] { String.class });
String fooReturned = fooMethod.invoke(fooClass.newInstance(), new String("I did it"));
If you own the source code of that jar library, you need to put it in properly package and wrap it again as a new jar library.
You may need to either fully qualify the Bag class, or import it.
As the title says, are there any libraries for extracting class, method, member and field dependency names from a .class file (bytecode)?
For example, if I a compiled Scala .class file uses something like this:
var xs = new List[java.lang.String]();
"blah" :: xs;
xs(0).charAt(0);
I should get that I use these classes and methods:
java.lang.String
java.lang.String#charAt
scala.collection.immutable.List
scala.collection.immutable.List#apply
Is there any library with API I can use in my own Scala program that can do this for me?
Here is ASM framework tutorial explaining how to collect dependencies from classes.
You need to be able to read the code of method bodies. I would use a byte code library such as ObjectWeb's ASM, BCEL or JavaAssist.