如何在Wildfly 9中启用JSP的动态编译?

时间:2015-08-03 19:28:28

标签: java jsp jboss compilation wildfly

我正在使用Wildfly 9.0.0.CR2。如何启用JSP的动态编译?我在另一个线程中找到了这个配置

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
    public sealed class MockDbSet<TEntity> : DbSet<TEntity>, IQueryable, 
        IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity> where TEntity : class
    {
        public MockDbSet(MockDbContext context)
        {
            // Get entity set for entity
            // Used when we figure out whether to generate
            // IDENTITY values
            EntitySet = ((IObjectContextAdapter) context).ObjectContext
                .MetadataWorkspace
                .GetItems<EntityContainer>(DataSpace.SSpace).First()
                .BaseEntitySets
                .FirstOrDefault(item => item.Name == typeof(TEntity).Name);

            Data = new ObservableCollection<TEntity>();
            Query = Data.AsQueryable();
        }

        private ObservableCollection<TEntity> Data { get; set; }

        Type IQueryable.ElementType
        {
            get { return Query.ElementType; }
        }

        private EntitySetBase EntitySet { get; set; }

        Expression IQueryable.Expression
        {
            get { return Query.Expression; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return Data.GetEnumerator();
        }

        public override ObservableCollection<TEntity> Local
        {
            get { return Data; }
        }

        IQueryProvider IQueryable.Provider
        {
            get { return new MockDbAsyncQueryProvider<TEntity>(Query.Provider); }
        }

        private IQueryable Query { get; set; }

        public override TEntity Add(TEntity entity)
        {
            GenerateIdentityColumnValues(entity);
            Data.Add(entity);
            return entity;
        }

        public override IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
        {
            foreach (var entity in entities)
                Add(entity);
            return entities;
        }

        public override TEntity Attach(TEntity entity)
        {
            return Add(entity);
        }

        public override TEntity Create()
        {
            return Activator.CreateInstance<TEntity>();
        }

        public override TDerivedEntity Create<TDerivedEntity>()
        {
            return Activator.CreateInstance<TDerivedEntity>();
        }

        public override TEntity Find(params object[] keyValues)
        {
            throw new NotSupportedException();
        }

        public override Task<TEntity> FindAsync(params object[] keyValues)
        {
            return FindAsync(CancellationToken.None, keyValues);
        }

        public override Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues)
        {
            throw new NotSupportedException();
        }

        private void GenerateIdentityColumnValues(TEntity entity)
        {
            // The purpose of this method, which is called when adding a row, 
            // is to ensure that Identity column values are properly initialized 
            // before performing the add.  If we were making a "real" Entity Framework 
            // Add() call, this task would be handled by the data provider and the 
            // value(s) would then be propagated back into the entity.  In the case 
            // of this mock, there is nothing that will do that, so we have to make
            // this at-least token effort to ensure the columns are properly initialized.

            // In SQL Server, an Identity column can be of one of the following 
            // data types:  tinyint, smallint, int, bigint, decimal (with a scale of 0), 
            // or numeric (with a scale of 0);  This method handles the integer types 
            // (the others are typically not used).
            foreach (var member in EntitySet.ElementType.Members.ToList())
            {
                if (member.IsStoreGeneratedIdentity)
                {
                    // OK, we've got a live one; do our thing.
                    //
                    // Note that we'll get the current value of the column and, 
                    // if it is nonzero, we'll leave it alone.  We do this because 
                    // the test data in our mock DbContext provides values for the 
                    // Identity columns and many of those values are foreign keys 
                    // in other entities (where we also provide test data).  We don't
                    // want to disturb any existing relationships defined in the test data.
                    Type columnDataType = null;
                    foreach (var metadataProperty in member.TypeUsage.EdmType.MetadataProperties.ToList())
                    {
                        if (metadataProperty.Name != "PrimitiveTypeKind")
                            continue;
                        switch ((PrimitiveTypeKind)metadataProperty.Value)
                        {
                            case PrimitiveTypeKind.SByte:
                                columnDataType = typeof(SByte);
                                break;
                            case PrimitiveTypeKind.Int16:
                                columnDataType = typeof(Int16);
                                break;
                            case PrimitiveTypeKind.Int32:
                                columnDataType = typeof(Int32);
                                break;
                            case PrimitiveTypeKind.Int64:
                                columnDataType = typeof(Int64);
                                break;
                            default:
                                throw new InvalidOperationException();
                        }

                        var identityColumnGetter = entity.GetType().GetProperty(member.Name).GetGetMethod();
                        var identityColumnSetter = entity.GetType().GetProperty(member.Name).GetSetMethod();

                        Int64 specifiedColumnValue = 0;
                        switch (columnDataType.Name)
                        {
                            case "SByte":
                                specifiedColumnValue = (SByte)identityColumnGetter.Invoke(entity, null);
                                break;
                            case "Int16":
                                specifiedColumnValue = (Int16)identityColumnGetter.Invoke(entity, null);
                                break;
                            case "Int32":
                                specifiedColumnValue = (Int32)identityColumnGetter.Invoke(entity, null);
                                break;
                            case "Int64":
                                specifiedColumnValue = (Int64)identityColumnGetter.Invoke(entity, null);
                                break;
                        }
                        if (specifiedColumnValue != 0)
                            break;

                        Int64 maxExistingColumnValue = 0;

                        switch (columnDataType.Name)
                        {
                            case "SByte":
                                foreach (var item in Local.ToList())
                                    maxExistingColumnValue = Math.Max(maxExistingColumnValue, (SByte)identityColumnGetter.Invoke(item, null));
                                identityColumnSetter.Invoke(entity, new object[] { (SByte)(++maxExistingColumnValue) });
                                break;
                            case "Int16":
                                foreach (var item in Local.ToList())
                                    maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int16)identityColumnGetter.Invoke(item, null));
                                identityColumnSetter.Invoke(entity, new object[] { (Int16)(++maxExistingColumnValue) });
                                break;
                            case "Int32":
                                foreach (var item in Local.ToList())
                                    maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int32)identityColumnGetter.Invoke(item, null));
                                identityColumnSetter.Invoke(entity, new object[] { (Int32)(++maxExistingColumnValue) });
                                break;
                            case "Int64":
                                foreach (var item in Local.ToList())
                                    maxExistingColumnValue = Math.Max(maxExistingColumnValue, (Int64)identityColumnGetter.Invoke(item, null));
                                identityColumnSetter.Invoke(entity, new object[] { (Int64)(++maxExistingColumnValue) });
                                break;
                        }
                    }
                }
            }
        }

        IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
        {
            return new MockDbAsyncEnumerator<TEntity>(Data.GetEnumerator());
        }

        IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
        {
            return Data.GetEnumerator();
        }

        public override TEntity Remove(TEntity entity)
        {
            Data.Remove(entity);
            return entity;
        }

        public override IEnumerable<TEntity> RemoveRange(IEnumerable<TEntity> entities)
        {
            foreach (var entity in entities)
                Remove(entity);
            return entities;
        }

        public override DbSqlQuery<TEntity> SqlQuery(string sql, params object[] parameters)
        {
            throw new NotSupportedException();
        }
    }

    internal class MockDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
    {
        internal MockDbAsyncQueryProvider(IQueryProvider queryProvider)
        {
            QueryProvider = queryProvider;
        }

        private IQueryProvider QueryProvider { get; set; }

        public IQueryable CreateQuery(Expression expression)
        {
            return new MockDbAsyncEnumerable<TEntity>(expression);
        }

        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
        {
            return new MockDbAsyncEnumerable<TElement>(expression);
        }

        public object Execute(Expression expression)
        {
            return QueryProvider.Execute(expression);
        }

        public TResult Execute<TResult>(Expression expression)
        {
            return QueryProvider.Execute<TResult>(expression);
        }

        public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
        {
            return Task.FromResult(Execute(expression));
        }

        public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
        {
            return Task.FromResult(Execute<TResult>(expression));
        }
    }

    internal class MockDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T>
    {
        public MockDbAsyncEnumerable(IEnumerable<T> enumerable)
            : base(enumerable)
        {
        }

        public MockDbAsyncEnumerable(Expression expression)
            : base(expression)
        {
        }

        IQueryProvider IQueryable.Provider
        {
            get { return new MockDbAsyncQueryProvider<T>(this); }
        }

        public IDbAsyncEnumerator<T> GetAsyncEnumerator()
        {
            return new MockDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
        }

        IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
        {
            return GetAsyncEnumerator();
        }
    }

    internal class MockDbAsyncEnumerator<T> : IDbAsyncEnumerator<T>
    {
        public MockDbAsyncEnumerator(IEnumerator<T> enumerator)
        {
            Enumerator = enumerator;
        }

        public void Dispose()
        {
            Enumerator.Dispose();
        }

        public T Current
        {
            get { return Enumerator.Current; }
        }

        object IDbAsyncEnumerator.Current
        {
            get { return Current; }
        }

        private IEnumerator<T> Enumerator { get; set; }

        public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(Enumerator.MoveNext());
        }
    }
}

但是,它不起作用,当我重新启动JBoss服务器时会导致以下异常...

    <subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">
        <configuration>
            <jsp-configuration development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>
        </configuration>
    </subsystem>

3 个答案:

答案 0 :(得分:4)

这是一个XML解析问题,此错误消息javax.xml.stream.XMLStreamException: ParseError就是明证。此特定行Unexpected element{urn:jboss:domain:web:1.4}subsystem的解析失败。

您可以查看XML模式文档以找出这些类型的XML解析问题。模式位于WildFly的docs文件夹下。

顺便说一句,您应该使用WildFly-9.0.1.Final构建版本,因为这是最新的候选版本。

您很可能需要对underow子系统进行更改。我已经更新了以下示例:

 <subsystem xmlns="urn:jboss:domain:undertow:2.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                </host>
            </server>
            <servlet-container name="default">
                <jsp-config development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>
                <websockets/>
            </servlet-container>
            <handlers>
                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
            </handlers>
            <filters>
                <response-header name="server-header" header-name="Server" header-value="WildFly/9"/>
                <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
            </filters>
        </subsystem>

我强烈建议您使用CLI进行此类更改:

/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=development,value=true)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=recompile-on-fail,value=true)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=check-interval,value=1)
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=modification-test-interval,value=1)

通过这种方式,您可以避免这些XML解析错误,而无需查找确切的XML模式。

答案 1 :(得分:3)

搜索子系统并在jsp config上添加它

<subsystem xmlns="urn:jboss:domain:undertow:1.1"><br>. . . .<br>   <servlet-container name="default" default-buffer-cache="default" stack-trace-on-error="local-only">
   <jsp-config development="true" check-interval="1" modification-test-interval="1" recompile-on-fail="true"/>


答案 2 :(得分:1)

确保您正在加载底部延伸。否则,子系统配置无法加载。除此之外,你的语法是正确的。

<extensions>
    <!-- other extensions here -->
    <extension module="org.wildfly.extension.undertow"/>
</extensions>