How do I solve this issue “object java.lang.Object in compiler mirror not found”?

I’m trying to restore the project Scala IDE to make it work on a more recent technical environment, i.e. Eclipse 2024-03, JDK17, and Scala 2.12.19.

I’m launching the test suite of this eclipse plugin project with org.eclipse.tycho:tycho-surefire-plugin:4.0.7:test.

The configuration of the tycho-surefire-plugin is :

<pluginManagement>
  <plugins>
    <plugin>
      <groupId>org.eclipse.tycho</groupId>
      <artifactId>tycho-surefire-plugin</artifactId>
      <configuration>
        <useUIHarness>false</useUIHarness>
        <useUIThread>false</useUIThread>
        <systemProperties combine.children="append">
          <aj.weaving.verbose>true</aj.weaving.verbose>
          <org.aspectj.weaver.showWeaveInfo>true</org.aspectj.weaver.showWeaveInfo>
          <org.aspectj.osgi.verbose>true</org.aspectj.osgi.verbose>
        </systemProperties>
        <frameworkExtensions>
          <frameworkExtension>
            <groupId>p2.osgi.bundle</groupId>
            <artifactId>org.eclipse.equinox.weaving.hook</artifactId>
            <version>${weaving.hook.plugin.version}</version>
          </frameworkExtension>
        </frameworkExtensions>
        <bundleStartLevel>
          <bundle>
            <id>org.eclipse.equinox.weaving.aspectj</id>
            <level>2</level>
            <autoStart>true</autoStart>
          </bundle>
        </bundleStartLevel>
        <argLine>${tycho.test.jvmArgs}</argLine>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>

The root project defines properties :

<weaving.hook.plugin.version>1.4.0.v20240213-1357</weaving.hook.plugin.version>
<tycho.test.weaving>-XX:+UnlockDiagnosticVMOptions -Dosgi.classloader.lock=classname</tycho.test.weaving>
<tycho.test.addOpens>--add-opens java.base/java.lang=ALL-UNNAMED</tycho.test.addOpens>
<tycho.test.jvmArgs>${tycho.test.addOpens} -Xmx2048m -Dsdtcore.headless -Dsdtcore.notimeouts -DretryFlakyTests=true ${tycho.test.weaving}</tycho.test.jvmArgs>

The tycho-surefire-plugin launched the following java command:

C:UsersnicolDownloadsjdk-17.0.4_windows-x64_binjdk-17.0.4binjava.exe -Dosgi.noShutdown=false -Dosgi.os=win32 -Dosgi.ws=win32 -Dosgi.arch=x86_64 --add-opens java.base/java.lang=ALL-UNNAMED -Xmx2048m -Dsdtcore.headless -Dsdtcore.notimeouts -DretryFlakyTests=true -XX:+UnlockDiagnosticVMOptions -Dosgi.classloader.lock=classname -Dosgi.clean=true -Daj.weaving.verbose=true -Dorg.aspectj.osgi.verbose=true -Dorg.aspectj.weaver.showWeaveInfo=true -jar C:Usersnicol.m2repositoryp2osgibundleorg.eclipse.equinox.launcher1.6.700.v20240213-1244org.eclipse.equinox.launcher-1.6.700.v20240213-1244.jar -data C:Usersnicolgitscala-ideorg.scala-ide.sdt.core.teststargetworkdata -install C:Usersnicolgitscala-ideorg.scala-ide.sdt.core.teststargetwork -configuration C:Usersnicolgitscala-ideorg.scala-ide.sdt.core.teststargetworkconfiguration -application org.eclipse.tycho.surefire.osgibooter.headlesstest -testproperties C:Usersnicolgitscala-ideorg.scala-ide.sdt.core.teststargetsurefire.properties

One of the test classes is :

package org.scalaide.core.testsetup


import org.eclipse.core.resources.IFile
import org.eclipse.core.resources.IncrementalProjectBuilder
import org.eclipse.core.runtime.NullProgressMonitor
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.ICompilationUnit
import org.eclipse.jdt.core.IPackageFragmentRoot
import org.eclipse.jdt.core.IProblemRequestor
import org.eclipse.jdt.core.JavaCore
import org.eclipse.jdt.core.WorkingCopyOwner
import org.eclipse.text.edits.ReplaceEdit
import org.junit.Assert.assertNotNull
import org.mockito.Mockito.mock
import org.mockito.Mockito.when
import org.scalaide.core.compiler.InteractiveCompilationUnit
import org.scalaide.core.internal.jdt.model.ScalaCompilationUnit
import org.scalaide.core.internal.jdt.model.ScalaSourceFile
import org.scalaide.core.IScalaProject
import org.scalaide.core.internal.project.ScalaProject

/** Base class for setting up tests that depend on a project found in the test-workspace.
 *
 *  Subclass this class with an `object'. The initialization will copy the given project
 *  from test-workspace to the target workspace, and retrieve the 'src/' package root in
 *  `srcPackageRoot'.
 *
 *  Reference the object form your test, so that the constructor is called and the project
 *  setup.
 *
 *  Example: `object HyperlinkDetectorTests extends TestProjectSetup("hyperlinks")'
 *
 */
class TestProjectSetup(projectName: String, srcRoot: String = "/%s/src/", val bundleName: String = "org.scala-ide.sdt.core.tests") extends ProjectBuilder {
  private[core] lazy val internalProject: ScalaProject = BlockingProgressMonitor.waitUntilDone {
    SDTTestUtils.internalSetupProject(projectName, bundleName)(_)
  }

  /** The ScalaProject corresponding to projectName, after copying to the test workspace. */
  override lazy val project: IScalaProject = internalProject

  /** The package root corresponding to /src inside the project. */
  lazy val srcPackageRoot: IPackageFragmentRoot = {
    val javaProject = JavaCore.create(project.underlying)

    javaProject.open(null)
    javaProject.findPackageFragmentRoot(new Path(srcRoot.format(projectName)))
  }

  assertNotNull(srcPackageRoot)

  srcPackageRoot.open(null)

  def file(path: String): IFile = {
    project.underlying.getFile(path)
  }

  /** Return the compilation unit corresponding to the given path, relative to the src folder.
   *  for example: "scala/collection/Map.scala"
   */
  def compilationUnit(path: String): ICompilationUnit = {
    val segments = path.split("/")
    srcPackageRoot.getPackageFragment(segments.init.mkString(".")).getCompilationUnit(segments.last)
  }

  /** Return a sequence of compilation units corresponding to the given paths. */
  def compilationUnits(paths: String*): Seq[ICompilationUnit] =
    paths.map(compilationUnit)

  /** Return a sequence of Scala compilation units corresponding to the given paths. */
  def scalaCompilationUnits(paths: String*): Seq[ScalaSourceFile] =
    paths.map(scalaCompilationUnit)

  /** Return the Scala compilation unit corresponding to the given path, relative to the src folder.
   *  for example: "scala/collection/Map.scala".
   */
  def scalaCompilationUnit(path: String): ScalaSourceFile =
    compilationUnit(path).asInstanceOf[ScalaSourceFile]

  def createSourceFile(packageName: String, unitName: String)(contents: String): ScalaSourceFile = {
    val pack = SDTTestUtils.createSourcePackage(packageName)(project)
    SDTTestUtils.createCompilationUnit(pack, unitName, contents).asInstanceOf[ScalaSourceFile]
  }

  def reload(unit: InteractiveCompilationUnit): Unit = {
    // first, 'open' the file by telling the compiler to load it
    unit.withSourceFile { (src, compiler) =>
      compiler.askReload(List(unit)).get
    }
  }

  def parseAndEnter(unit: InteractiveCompilationUnit): Unit = {
    unit.withSourceFile { (src, compiler) =>
      val dummy = new compiler.Response[compiler.Tree]
      compiler.askParsedEntered(src, false, dummy)
      dummy.get
    }
  }

  def findMarker(marker: String) = SDTTestUtils.findMarker(marker)

  /** Emulate the opening of a scala source file (i.e., it tries to
   * reproduce the steps performed by JDT when opening a file in an editor).
   *
   * @param srcPath the path to the scala source file
   * */
  def open(srcPath: String): ScalaSourceFile = {
    val unit = scalaCompilationUnit(srcPath)
    openWorkingCopyFor(unit)
    reload(unit)
    unit
  }

  /** Open a working copy of the passed `unit` */
  private def openWorkingCopyFor(unit: ScalaSourceFile): Unit = {
    val requestor = mock(classOf[IProblemRequestor])
    // the requestor must be active, or unit.getWorkingCopy won't trigger the Scala
    // structure builder
    when(requestor.isActive()).thenReturn(true)

    val owner = new WorkingCopyOwner() {
      override def getProblemRequestor(unit: org.eclipse.jdt.core.ICompilationUnit): IProblemRequestor = requestor
    }

    // this will trigger the Scala structure builder
    unit.getWorkingCopy(owner, new NullProgressMonitor)
  }

  /** Wait until the passed `unit` is entirely typechecked. */
  def waitUntilTypechecked(unit: ScalaCompilationUnit): Unit = {
    // give a chance to the background compiler to report the error
    unit.withSourceFile { (source, compiler) =>
      compiler.askLoadedTyped(source, true).get // wait until unit is typechecked
    }
  }

  /** Open the passed `source` and wait until it has been fully typechecked.*/
  def openAndWaitUntilTypechecked(source: ScalaSourceFile): Unit = {
    val sourcePath = source.getPath()
    val projectSrcPath = project.underlying.getFullPath() append "src"
    val path = sourcePath.makeRelativeTo(projectSrcPath)
    open(path.toOSString())
    waitUntilTypechecked(source)
  }

  /**
   * Allows to modify sources in test workspace.
   *
   * @param compilationUnitPath path to file which we'll change
   * @param lineNumber line which will be removed (line numbers start from 1)
   * @param newLine code inserted in place of line with lineNumber
   */
  def modifyLine(compilationUnitPath: String, lineNumber: Int, newLine: String): Unit = {
    val lineIndex = lineNumber - 1
    val cu = compilationUnit(compilationUnitPath)
    val code = cu.getSource
    val lines = code.split('n').toList
    val newLines = lines.updated(lineIndex, newLine)
    val newCode = newLines.mkString("n")

    val textEdit = new ReplaceEdit(0, code.length(), newCode)
    cu.applyTextEdit(textEdit, new NullProgressMonitor)
    cu.save(new NullProgressMonitor, true)
  }

  /**
   * Be aware that it can be heavy. Moreover, it's needed to ensure that
   * events are already properly propagated after the build.
   */
  def buildIncrementally(): Unit =
    project.underlying.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new NullProgressMonitor)
}

The stacktrace corresponding to that test is :

scala.reflect.internal.MissingRequirementError: object java.lang.Object in compiler mirror not found.
        at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:24)
        at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:25)
        at scala.reflect.internal.Mirrors$RootsBase.$anonfun$getModuleOrClass$5(Mirrors.scala:61)
        at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:61)
        at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:51)
        at scala.reflect.internal.Mirrors$RootsBase.getRequiredClass(Mirrors.scala:51)
        at scala.reflect.internal.Definitions$DefinitionsClass.ObjectClass$lzycompute(Definitions.scala:301)
        at scala.reflect.internal.Definitions$DefinitionsClass.ObjectClass(Definitions.scala:301)
        at scala.reflect.internal.Definitions$DefinitionsClass.init(Definitions.scala:1511)
        at scala.tools.nsc.Global$Run.<init>(Global.scala:1225)
        at scala.tools.nsc.interactive.Global$TyperRun.<init>(Global.scala:1323)
        at scala.tools.nsc.interactive.Global.newTyperRun(Global.scala:1346)
        at scala.tools.nsc.interactive.Global.<init>(Global.scala:294)
        at org.scalaide.core.internal.compiler.ScalaPresentationCompiler.<init>(ScalaPresentationCompiler.scala:55)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.liftedTree1$1(PresentationCompilerProxy.scala:156)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.create(PresentationCompilerProxy.scala:153)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.initialize(PresentationCompilerProxy.scala:118)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.obtainPc$1(PresentationCompilerProxy.scala:80)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.internal(PresentationCompilerProxy.scala:100)
        at org.scalaide.core.internal.compiler.PresentationCompilerProxy.apply(PresentationCompilerProxy.scala:58)
        at org.scalaide.core.compiler.InteractiveCompilationUnit.withSourceFile(InteractiveCompilationUnit.scala:201)
        at org.scalaide.core.compiler.InteractiveCompilationUnit.withSourceFile$(InteractiveCompilationUnit.scala:200)
        at org.scalaide.core.internal.jdt.model.ScalaSourceFile.withSourceFile(ScalaSourceFile.scala:70)
        at org.scalaide.core.testsetup.TestProjectSetup.reload(TestProjectSetup.scala:88)
        at org.scalaide.core.completion.CompletionTests.t1001218(CompletionTests.scala:161)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
        at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:316)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:240)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:214)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:155)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
        at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:140)
        at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:651)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:588)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1459)
        at org.eclipse.equinox.launcher.Main.main(Main.java:1432)

The target-platform-configuration uses a target-platform file target-platform-2.12.target :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
<target name="target-platform">
  <locations>
    <location includeDependencyDepth="none" includeSource="true"
      missingManifest="generate" type="Maven">
      <dependencies>
        <dependency>
          <groupId>org.scala-lang</groupId>
          <artifactId>scala-library</artifactId>
          <version>2.12.19</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-lang</groupId>
          <artifactId>scala-compiler</artifactId>
          <version>2.12.19</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-lang</groupId>
          <artifactId>scala-reflect</artifactId>
          <version>2.12.19</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-refactoring</groupId>
          <artifactId>org.scala-refactoring.library_2.12.2</artifactId>
          <version>0.13.0</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scalariform</groupId>
          <artifactId>scalariform_2.12</artifactId>
          <version>0.2.10</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-lang.modules</groupId>
          <artifactId>scala-xml_2.12</artifactId>
          <version>2.3.0</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-ide</groupId>
          <artifactId>org.scala-ide.zinc.compiler.bridge</artifactId>
          <version>4.7.1-SNAPSHOT</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.scala-ide</groupId>
          <artifactId>org.scala-ide.zinc.library</artifactId>
          <version>4.7.1-SNAPSHOT</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.fusesource.jansi</groupId>
          <artifactId>jansi</artifactId>
          <version>2.4.1</version>
          <type>jar</type>
        </dependency>
      </dependencies>
    </location>
    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
      <repository location="https://download.eclipse.org/releases/2024-03"/>
      <unit id="org.apache.ant" version="0.0.0"/>
    </location>
  </locations>
</target>

I tried to do minimalist example without tycho/osgi and I didn’t have any issue with it :

import scala.tools.nsc.Global
import scala.tools.nsc.Settings

// Define the ScalaCompiler class with an integrated main method
object ScalaCompiler {
  // Method to compile a specified Scala file
  def compileScalaFile(fileName: String): Unit = {
    val settings = new Settings()
    settings.usejavacp.value = true
    settings.withErrorFn(err => println(s"error while compiling: $err"))

    val compiler = new Global(settings)
    val run = new compiler.Run
    val sourceFiles = run.compile(List(fileName))
  }

  // Main method as the entry point
  def main(args: Array[String]): Unit = {
    if (args.length > 0) {
      compileScalaFile(args(0))
    } else {
      println("No filename provided. Usage: scala ScalaCompiler <filename>")
    }
  }
}
class Test {
   println ("Hello World!")
}

This worked without any errors :

scalac ScalaCompiler.scala

java -cp .;.m2repositoryorgscala-langscala-library2.12.19scala-library-2.12.19.jar;.m2repositoryorgscala-langscala-compiler2.12.19scala-compiler-2.12.19.jar;.m2repositoryorgscala-langscala-reflect2.12.19scala-reflect-2.12.19.jar ScalaCompiler Test.scala

I suspect there is something with the OSGi environment that prevents java.lang.Object from being visible by the scala compiler.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật