diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java index 9ebfe2cdb16d..2834bea4f149 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidJpsUtil.java @@ -158,6 +158,8 @@ class AndroidJpsUtil { public static Set getExternalLibraries(@NotNull ProjectPaths paths, @NotNull Module module) { final Set result = new HashSet(); fillClasspath(paths, module, null, result, new HashSet(), false); + + // todo: add annotations.jar to result return result; } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java index 9bf5d2ca049c..94e6eba01b33 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java @@ -46,13 +46,17 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -520,20 +524,35 @@ public class AndroidFacet extends Facet { if (resFolderPath == null) { return; } + final List filesToAdd = new ArrayList(); final VirtualFile resFolder = LocalFileSystem.getInstance().findFileByPath(resFolderPath); - if (resFolder == null) { - return; + if (resFolder != null) { + filesToAdd.add(resFolder); } - for (VirtualFile root : sdk.getRootProvider().getFiles(OrderRootType.CLASSES)) { - if (root == resFolder) { - return; + if (platform.needToAddAnnotationsJarToClasspath()) { + final String sdkHomePath = FileUtil.toSystemIndependentName(platform.getSdkData().getLocation()); + final VirtualFile annotationsJar = JarFileSystem.getInstance().findFileByPath( + sdkHomePath + AndroidSdkUtils.ANNOTATIONS_JAR_RELATIVE_PATH + JarFileSystem.JAR_SEPARATOR); + filesToAdd.add(annotationsJar); + } + + addFilesToSdkIfNecessary(sdk, filesToAdd); + } + + private static void addFilesToSdkIfNecessary(@NotNull Sdk sdk, @NotNull Collection files) { + final List newFiles = new ArrayList(files); + newFiles.removeAll(Arrays.asList(sdk.getRootProvider().getFiles(OrderRootType.CLASSES))); + + if (newFiles.size() > 0) { + final SdkModificator modificator = sdk.getSdkModificator(); + + for (VirtualFile file : newFiles) { + modificator.addRoot(file, OrderRootType.CLASSES); } + modificator.commitChanges(); } - final SdkModificator modificator = sdk.getSdkModificator(); - modificator.addRoot(resFolder, OrderRootType.CLASSES); - modificator.commitChanges(); } private static void updateDependenciesInPropertyFile(@NotNull final PropertiesFile projectProperties, diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java index 10badcdde18d..e88bdb910992 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java @@ -22,6 +22,7 @@ import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Computable; @@ -32,6 +33,10 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.util.containers.OrderedSet; import org.jetbrains.android.compiler.AndroidCompileUtil; +import org.jetbrains.android.sdk.AndroidPlatform; +import org.jetbrains.android.sdk.AndroidSdkAdditionalData; +import org.jetbrains.android.sdk.AndroidSdkType; +import org.jetbrains.android.sdk.AndroidSdkUtils; import org.jetbrains.android.util.AndroidCommonUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -284,9 +289,38 @@ public class AndroidRootUtil { Set files = new HashSet(); OrderedSet libs = new OrderedSet(); fillExternalLibrariesAndModules(module, files, libs, new HashSet(), false); + + addAnnotationsJar(module, libs); return libs; } + private static void addAnnotationsJar(Module module, OrderedSet libs) { + final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + if (sdk == null || !sdk.getSdkType().equals(AndroidSdkType.getInstance())) { + return; + } + + final String sdkHomePath = sdk.getHomePath(); + if (sdkHomePath == null) { + return; + } + + final AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); + if (data == null) { + return; + } + final AndroidPlatform platform = data.getAndroidPlatform(); + + if (platform != null && platform.needToAddAnnotationsJarToClasspath()) { + final String annotationsJarPath = FileUtil.toSystemIndependentName(sdkHomePath) + AndroidSdkUtils.ANNOTATIONS_JAR_RELATIVE_PATH; + final VirtualFile annotationsJar = LocalFileSystem.getInstance().findFileByPath(annotationsJarPath); + + if (annotationsJar != null) { + libs.add(annotationsJar); + } + } + } + @NotNull public static Set getDependentModules(Module module, VirtualFile moduleOutputDir) { diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidPlatform.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidPlatform.java index ceb99cd28c63..e3f4aaa09afe 100644 --- a/plugins/android/src/org/jetbrains/android/sdk/AndroidPlatform.java +++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidPlatform.java @@ -179,4 +179,8 @@ public class AndroidPlatform { result = 31 * result + myTarget.hashCode(); return result; } + + public boolean needToAddAnnotationsJarToClasspath() { + return myTarget.getVersion().getApiLevel() <= 15; + } } diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java index 3c3ce9d73cd1..77f2ab1eb7aa 100644 --- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java +++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java @@ -73,6 +73,7 @@ public class AndroidSdkUtils { public static final String DEFAULT_PLATFORM_NAME_PROPERTY = "AndroidPlatformName"; @NonNls public static final String ANDROID_HOME_ENV = "ANDROID_HOME"; + @NonNls public static final String ANNOTATIONS_JAR_RELATIVE_PATH = "/tools/support/annotations.jar"; private AndroidSdkUtils() { } @@ -128,6 +129,16 @@ public class AndroidSdkUtils { result.add(new OrderRoot(resFolder, OrderRootType.CLASSES)); } } + + if (sdkPath != null) { + // todo: check if we should do it for new android platforms (api_level >= 15) + final VirtualFile annotationsJar = JarFileSystem.getInstance() + .findFileByPath(FileUtil.toSystemIndependentName(sdkPath) + ANNOTATIONS_JAR_RELATIVE_PATH + JarFileSystem.JAR_SEPARATOR); + if (annotationsJar != null) { + result.add(new OrderRoot(annotationsJar, OrderRootType.CLASSES)); + } + } + return result; }