章节目录:

要求

 Java 5.0 - 8.0

优点

并非所有被测系统组件都能通过定义的线路协议或 API 进行通信,此类协议或 API 的虚拟化通过轻松重新配置被测应用程序(AUT)以将通讯报文定向到不同的主机或不同的端点来实现。在某些情况下,集成通过 API 进行,如果不直接修改应用程序代码,就无法对其进行控制。

对于使用 Java AUT 的团队,Parasoft 的 Java Virtualization Agent 可用于直接录制应用程序 JVM 中的 Java 方法调用,并将这些调用的行为虚拟化。Parasoft Java Virtualization Agent 尤其适用于虚拟化 RMI、远程 EJB 调用或任何其他提供功能和/或与依赖系统连接的内部开发代码。

方法

启动 AUT 时,会将此 Parasoft 代理配置为 JVM 启动参数。该代理的配置会显示它对每个指定的目标类和方法是处于非活动、录制还是虚拟化模式。

一旦代理进入录制模式,您就可以使用想要录制的行为执行 AUT。此代理会将方法调用数据保存到本地文件中。要创建代表录制行为的虚拟资产,您可以将该文件提供给 Virtualize 的虚拟资产创建向导。

录制所需行为后,可以将代理切换到虚拟化模式,并使用 Virtualize 虚拟资产的 HTTP 端点进行配置。这样,相同的方法调用将重定向到 Virtualize PVA 而不是实际方法;它们将返回之前录制的对象实例。


以下是在 Oracle WebLogic medrec 应用程序样本上录制的 PVA 样本:

Java Virtualization 模式

有两种不同的虚拟化模式可用于录制 Java 方法调用并虚拟化其返回值:

  • Class Method Virtualization:为类的调用者虚化返回值。
  • Call Virtualization:虚拟化从特定位置调用某些方法的方式。

最佳应用模式取决于应用的需求。您可以混用这两种虚拟化模式,也可以混用每种指定类/方法的多种模式。

Class Method Virtualization

在这种模式下,V 类的调用者会收到经过虚拟化的返回值。本质上,无论 V 类的虚拟化方法如何被调用(从哪里被调用),都会全局性地改变 V 类的行为。

配置这种类型的虚拟化需要提供完全限定类名以及要虚拟化(或要在录制模式下录制)的方法名称。在虚拟化模式下,这些指定方法的返回值将被更改。

Call Virtualization

在该模式中,将虚拟化某些方法从特定位置被调用的方式。您需要提供:

  • 调用类的完全限定名称。该类即为将方法调用虚拟化应用到其他类和方法的类。
  • 调用类中要进行虚拟化的方法列表。当这些方法调用其他特定的对象和方法(下面的项目)时,它们将被虚拟化。
  • 调用类中要虚拟化的类类型的完全限定名称。它是要应用虚拟化的声明接口或对象类型。
  • 应用虚拟化的方法列表。

这种模式尤其适用于远程 EJB 方法调用虚拟化。调用类通常为控制器对象。在该对象中,远程 EJB 调用使用某些已声明的远程接口类型进行。以下为如何使用这种模式对远程 EJB 调用进行虚拟化的图示:

代理配置

配置 Java 应用程序以使用代理

  1. ParasoftJavaVirtAgent.jar 和其他随附文件复制到您的应用程序可访问的文件路径位置。
  2. 在应用程序的“java”启动可执行文件中添加以下 JVM 参数(以单行形式提供,在每个 -D 参数前空格):

    -javaagent:"C:/PathTo/ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:/Path/AgentConfig.xml" -Dparasoft.virtualize.log.config="C:/Path/logging.properties"

如果您的应用程序记录了 ClassNotFoundException 异常,请尝试添加以下附加标记:

-Xbootclasspath/a:"C:/Path/ParasoftJavaVirtAgent.jar;C:/Path/xstream-1.4.2.jar"

Oracle WebLogic 

编辑 setDomainEnv.sh 服务器启动脚本,添加上述参数。无需设置 Xbootclasspath。

Apache Karaf/ServiceMix

必须设置 Xbootclasspath。还需要调整委托给父类加载器的 Java 包。这样能够确保您的 OSGi 捆绑程序在运行时可查看 Parasoft Agent 运行时库。在 Apache Service Mix 中,可通过在 /etc/custom.properties 中的 org.osgi.framework.bootdelegation 属性末尾添加以下内容(均在一行)来实现:

,com.parasoft.virtualize.java.agent.runtime,com.parasoft.virtualize.java.agent.runtime.*

,com.thoughtworks.xstream.*

IBM WebSphere Application Server

无需编辑服务器启动文件。您可以使用 IBM Integrated Solutions Console for WAS 来配置代理。前往 Application servers > [server name] > Process definition >Java Virtual Machine。在“Generic JVM Arguments”字段中,提供代理配置参数。例如(均在一行,每个 -D 参数之间用空格隔开):

-javaagent:C:/Parasoft/ParasoftJavaVirtAgent.jar -Dparasoft.virtualize.config=C:/Parasoft/PlantsByWebSphere.xml -Dparasoft.virtualize.log.config=C:/Parasoft/logging.properties


如果 -javaagent 路径输入错误或文件被删除,导致服务器无法启动,可以通过编辑 [was.install.root]/profiles/[profile name]/config/cells/[cellname]/nodes/[node name]/servers/server1/server.xml 并删除错误参数(搜索 ParasoftJavaVirtAgent.jar 或您提供的其他参数)来解决。

WebSphere Application Server 将覆盖代理的日志配置,使其始终将输出重定向到自己的日志框架。您可以使用 IBM Console 在 Logging and Tracing > server1 > Change log detail levels 下配置所需的日志级别。查找 com.parasoft.virtualize.* 组件,并根据需要调整日志级别。Parasoft Java Virtualization 代理日志可在 [was.install.root]/profiles/[profilename]/logs/[server name]/native_stdout.log 下找到。

IBM WebSphere Community Edition

必须设置 Xbootclasspath

配置受虚拟资产控制的代理

JavaVirtualization.pva(包含在 zip 压缩包中)部署到 Virtualize 服务器,并将代理的 Virtualize 服务器 URL 设置为指向该资产。该资产将能:

  • 接收来自 Java 代理的消息。
  • 响应消息。
  • 启用运行时远程切换 Java 代理模式的功能。
  • 接收代理的日志消息。
  • 接收代理的录制通讯报文。


需在代理上配置以下设置:

-Dparasoft.virtualize.remote.mode=true

如果为 true,则启用运行时切换模式的功能。这种模式切换通过更新 JavaVirtualization.pva 使用的环境完成。检查 PVA,验证是否可以通过将适当的环境设置为活动状态来控制模式。

logging.properties

要启用向服务器发送 java util logging,请将其设置为 com.parasoft.virtualize.java.agent.log.ServerHandler

AgentConfig.xml

要让代理将录制的通讯报文发送到 Virtualize 服务器,请将 AgentConfig.xml 中的“recorderType”设置为“HTTP_TRAFFIC_SERVER”(有关 AgentConfig.xml 的详情,请参阅后续内容)。

配置代理日志

该代理包含一个 logging.properties 文件,对其进行编辑可调整代理创建的本地日志文件的详细级别和位置。由于该代理使用 Java 的标准内建日志框架,因此适用于该框架的属性和设置也适用于该代理。(请参阅 http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html)一般而言,应考虑以下两个属性:

com.parasoft.virtualize.java.agent.level=ALL|FINEST|FINER|FINE|INFO|WARNING|SEVERE

java.util.logging.FileHandler.pattern=C:\path/parasoft_java_agent_log.%g.txt

请注意,某些应用服务器平台会覆盖代理的 logging.properties 文件设置的日志记录位置和级别。在这种情况下,您可以使用应用服务器自己的框架来调整日志级别。请参阅“配置 Java 应用程序以使用代理”部分(上文)中有关特定服务器配置的说明。

默认情况下,如果应用程序 JVM 通过代理成功启动,则会显示以下日志语句:

[Parasoft Java Virtualization Agent: INFO {timestamp}] class file transformer initialized using configuration file {file path}

加载应用程序并对其进行检测后,默认(info)日志级别下应出现以下一条或多条日志语句:

[Parasoft Java Virtualization Agent: INFO {timestamp}] transforming {class name provided in the agent configuration XML}

AgentConfig.xml 概述

AgentConfig.xml 是代理专用的 XML 描述符。它告诉代理要应用哪些类和方法,以及以何种模式(虚拟化、录制等)应用。下面是一个配置文件示例:

<ParasoftJavaVirtAgent>
	<virtualizeServer>
		<url>http://localhost:9080/ParaBankJavaLoanRequest</url>
	</virtualizeServer>
	<recorderType>HTTP_TRAFFIC_FILE</recorderType>
<localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath>
	<callVirtualizationClasses>
		<callVirtualizationClass>
		<callingMethods>
			<method>
				<className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className>
				<methodName>requestLoan</methodName>
				<argumentTypes>
					<string></string>
				</argumentTypes>
				<mode>INACTIVE</mode>
			</method>
		</callingMethods>
		<virtualizedMethods>
			<method>
				<className>com.parasoft.parabank.domain.logic.LoanProvider</className>
				<methodName>requestLoan</methodName>
					<argumentTypes>
						<string></string>
					</argumentTypes>
				<mode>INACTIVE</mode>
			</method>
		</virtualizedMethods>
	</callVirtualizationClass>
</callVirtualizationClasses>
<methodVirtualizationClasses>
			<method>
		<className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
			<methodName>requestLoan</methodName>
			<argumentTypes>
					<string></string>
				</argumentTypes>
				<mode>RECORD</mode>
			</method></methodVirtualizationClasses>
</ParasoftJavaVirtAgent>

代理配置部分

<virtualizeServer>
	<url>http://virtServerHost:9080/ParaBankJavaLoanRequest</url>
</virtualizeServer>

适用于 VIRTUALIZE 模式方法。它表示 Virtualize 服务器和先前从录制中生成的 PVA 的 HTTP 路径。

<localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath>

是保存 Java 方法调用的绝对路径(在 RECORD 模式下)。请注意,新通讯报文默认情况下将追加到现有通讯报文文件中。因此,多次录制同一通话可能会导致文件中的数据重复。

<callVirtualizationClasses>  </callVirtualizationClasses>

可以包含一个或多个 <callVirtualizationClass> 元素。它规定了调用虚拟化模式的类和方法。请注意,目前不支持使用

<argumentTypes><string>argTypesNYI</string></argumentTypes>

为方法指定完全限定签名。

<callingMethods> 元素指定应从哪些方法应用调用虚拟化。<virtualizedMethods> 元素指定的方法是实际被虚拟化的方法。

<mode> </mode>

可以取 INACTIVE、RECORD 或 VIRTUALIZE 三个值中的一个用于指定的任何方法。INACTIVE 告诉代理,应该调用原始方法,而无需录制调用、执行虚拟化或以其他方式改变方法的行为。

<methodVirtualizationClasses>

指定应用 Class Method Virtualization 模式的类及其方法列表。

从这个示例中可以看出,两种虚拟化模式可以混用,并且可以为每个指定的类/方法混用多种模式。

生成 PVA

使用所需场景以及在 RECORD 模式配置的一些类/方法运行应用程序后,即可从 AUT 中获取录制的文件,并通过通讯报文提供给 Virtualize 的 PVA 创建向导。

 根据通讯报文创建 PVA 时,请选择 HTTP 选项(代理生成的 Java 录制文件格式为 HTTP 通讯报文文件,对象转换为 XML 表示形式)。

将为每个唯一的方法创建一个响应器,因为每个录制的方法在 XML 文件中都有唯一的 XML 根元素。每个响应器都将以“多响应”模式创建,以反映录制的各种输入参数/返回值。

使用生成的 PVA

部署 PVA 后,将 AgentConfig.xml 切换到 VIRTUALIZE 模式,并将 url 元素指向 PVA 部署 HTTP 端点。该代理会使应用程序的 JVM 将指定的方法调用远程重定向到 Virtualize(通过 HTTP),而不是调用实际的方法。在 Virtualize 中配置的返回对象将用作这些方法的返回值。

假设和限制

Java Virtualization Agent 尤其适用于录制和虚拟化无状态方法调用,这些方法调用在应用程序内的另一个子组件中执行某些功能,或远程调用到某些依赖项中。

以下是使用该版本代理时应注意的一些限制:

  • 不录制对象状态。
  • 没有针对每个实例的控制——所有控制都在类/对象类型级别执行。
  • 不录制/虚拟化抛出的异常。
  • 调用方法参数值不会影响虚拟化返回值。
  • 方法由类名和方法名标识,还没有完全限定签名。
  • 应用程序需要重新启动才能应用模式更改。

教程:ParaBank

Class Method Virtualization

首先,让我们尝试 Class Method Virtualization 模式,将 ConfigurableLoanProvider 类的行为虚拟化,无论 ParaBank 中配置了哪种贷款提供商,都会调用该类请求贷款。

  1. 在 Virtualize 中创建 ParaBank 项目。
  2. 使用上文提供的 AgentConfig.xml 示例(将 localRecordingFilePath 更改为您想要在环境中保存录制文件的位置)。
  3. 打开 ParaBank 运行配置,添加 VM 参数(均在一行,每个 -D 参数之间用空格隔开):

    -javaagent:"C:\PATH\ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:\PATH\AgentConfig.xml" -Dparasoft.virtualize.log.config="C:\PATH\logging.properties"
  4. 运行配置,然后按如下步骤运行应用程序:
    1. 使用 john/demo 登录 ParaBank。
    2. 点击请求贷款链接。
    3. 申请本金为 1000、首付为 200 的贷款。
    4. 申请另一笔 10000 的贷款,首付为 100。
  5. 验证是否在本地 RecordingFilePath 中指定的位置创建了文件
  6. 关闭 ParaBank。

  7. 通过通讯报文创建新的 PVA,步骤如下:
    1. 选择通讯报文 > 生成固定消息,指定通讯报文文件的位置,然后点击下一步。 
    2. 选择基于操作/类型将消息分组,然后点击下一步
    3. 在消息分组审查步骤,禁用自动配置选项,以便在下一步中手动配置请求匹配选项,然后点击下一步
    4. 在请求匹配步骤,删除现有参数,只添加 loanAmountdownPayment 元素作为请求体的相关参数,然后点击下一步
    5. 指定一个与 AgentConfig.xml 中的设置相匹配的部署端点。在该情况下使用:

      /ParaBankJavaLoanRequest

      <virtualizeServer>
      	<url>http://localhost:9080/ParaBankJavaLoanRequest</url>
      </virtualizeServer>
    6. 点击完成
      PVA 将在多响应模式下创建一个响应器。由于本例中只将一个方法虚拟化,因此只创建了一个响应器。
  8. 编辑响应,添加以下内容: <loanProviderName>Parasoft Virtualize</loanProviderName> 
  9. 使用以下方法将 AgentConfig.xml 模式切换为 VIRTUALIZE:

    <methodVirtualizationClasses>
    <method>
    <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
    	<methodName>requestLoan</methodName>
    	<argumentTypes>
    		<string></string>
    	</argumentTypes>
    	<mode>VIRTUALIZE</mode>
    </method>
    </methodVirtualizationClasses>
  10. 再次运行 ParaBank,请求与之前录制金额相同的贷款。需注意,贷款提供商标签将显示您在 Virtualize 响应器中指定的内容。在 Virtualize 中启用监控虚拟资产的功能,即可查看由 ParaBank 生成并由 Virtualize 接收的请求和响应。

Call Virtualization

接下来,让我们尝试 Call Virtualization 模式。此练习的目标是将 BankManagerImpl.java, method requestLoan() 下的以下调用行虚拟化:

LoanResponse loanResponse = loanProvider.requestLoan(loanRequest);

为此,我们需要对代理做出指示:

  • BankManagerImpl 是调用类。
  • 其 requestLoan() 方法为调用方法。
  • 由于贷款提供商的对象类型是 LoanProvider,因此该类为虚拟化类,我们要虚拟化的方法调用为 requestLoan()。(在这个例子中,调用方法名称和虚拟化方法名称相同只是一个巧合。)

尝试 Call Virtualization 模式:

  1. 将类方法虚拟化设置为 INACTIVE。

    <methodVirtualizationClasses>
    <method>
    <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className>
    	<methodName>requestLoan</methodName>
    	<argumentTypes>
    		<string></string>
    	</argumentTypes>
    	<mode>INACTIVE</mode>
    </method>
    </methodVirtualizationClasses>
  2. 将 Call Virtualization 类模式设置为 RECORD。

    <callVirtualizationClass>
    	<callingMethods>
    		<method>
    			<className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className>
    			<methodName>requestLoan</methodName>
    			<argumentTypes>
    				<string></string>
    			</argumentTypes>
    			<mode>RECORD</mode>
    		</method>
    	</callingMethods>
    <virtualizedMethods>
    		<method>
    			<className>com.parasoft.parabank.domain.logic.LoanProvider</className>
    			<methodName>requestLoan</methodName>
    			<argumentTypes>
    				<string></string>
    			</argumentTypes>
    			<mode>RECORD</mode>
    		</method>
    	</virtualizedMethods>
    </callVirtualizationClass>
  3. 运行 ParaBank 并申请贷款额度;重复上一个练习中的步骤 4 到步骤 7。
  4. 将 callVirtualizationClass 部分下的模式切换为 VIRTUALIZE。
  5. 再次运行 ParaBank。注意它现在是如何使用 Virtualize 来模拟方法调用的。
  • No labels