tags:

views:

428

answers:

2

I'm working on a Scala project that is importing two java libraries. Through poor planning, the two java libraries have similar package names, one with com on the front, one without.

The problem is that Scala is looking for the package with com in front first, and telling me that the package doesn't exist. If I remove all references to the library with com in front of the package, the compile works.

To show an example that makes sense:

In foo.jar we have a package company.product.core

In bar.jar we have a package com.company.product.other.

If both jars are on the classpath, the line:

import company.product.core.ClassName

Fails with the error "value core is not a member of package com.companyname.product" If we remove bar.jar, the compile works fine.

Is Scala trying to save me from typing com.? Is there a way to tell it to import only what I tell it to?

+6  A: 

Use _root_ prefix in import statements. It makes package resolution absolute.

import _root_.company.product.core.ClassName
import _root_.com.company.product.other.ClassName

Referring to you comment: with relative imports you could do something like this. It basically saves you some typing.

import _root_.company.product.core
import ClassAFromCore
import ClassBFromCore
Juha Syrjälä
This works, but I'm curious as to why Scala does this?
Jeff
Scala enables a relative matching from a prior package import. Like, after "import scala.collection._" you can just call "import mutable._" to get "scala.collection.mutable._". It causes lots of fun things with the "net" package name.
Tristan Juricek
@Tristan import collection._ works also (scala is already imported)
Thomas Jung
A: 

I'll guess that the place you put that import line belongs to a package starting with "com.", like this:

package com.whatever
import company.product.core.ClassName

That means all of com., including com.company, is part of the scope, and that com.company is, therefore, shadowing the company that is root, as objects closer in the hierarchy scope shadow those farther.

For whatever it is worth, Scala 2.8 will have slightly different rules. Now, if I define my package as:

package com.c.b.a

then only a will be in scope. If I wish to get the previous behavior, I need to do:

package com
package c
package b
package a
Daniel